Commit 2327629c authored by mae's avatar mae
Browse files

Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

parents 7d936a39 246671c4
......@@ -57,6 +57,7 @@
\o \l{Debugging with Qt Creator}
\o \l{CMake Support in Qt Creator}
\o \l{Support for Generic Projects in Qt Creator}
\o \l{Handling External Libraries}
\o \l{Tips and Tricks}
\o \l{Keyboard Shortcuts}
\o \l{Glossary}
......@@ -694,7 +695,6 @@
*/
/*!
\contentspage index.html
\previouspage creator-writing-program.html
......@@ -1358,7 +1358,7 @@
\contentspage index.html
\previouspage creator-debugging.html
\page creator-cmake-support.html
\nextpage creator-tips.html
\nextpage creator-generic-projects.html
\title CMake Support in Qt Creator
......@@ -1412,7 +1412,7 @@
\contentspage index.html
\previouspage creator-cmake-support.html
\page creator-generic-projects.html
\nextpage creator-tips.html
\nextpage creator-external-library-handling.html
\title Support for Generic Projects in Qt Creator
......@@ -1428,10 +1428,65 @@
*/
/*!
\contentspage index.html
\previouspage creator-generic-projects.html
\page creator-external-library-handling.html
\nextpage creator-tips.html
\title Handling External Libraries
Knowing external libraries is not only important for the
underlying build system, but also for Qt Creator itself.
This way, it can support code completion and syntax highlighting
for external libraries as if they were part of the current
project or the Qt library.
The way to add a library to the project depends on the
project type, which influcences the build system used.
The following sections describe the the procedure required
for each project type.
\section1 QMake Projects (the default)
Open your your (ending in \c{.pro}) file from the
\gui{Projects} pane, which will now show up in the editor.
Follow the description in the
\l{http://doc.qtsoftware.com/latest/make-project-files.html#declaring-other-libraries}
{Declaring other Libraries} section of the Qt documentation.
If your project does sucessfully build and link against
the external library, syntax completion and highlighting
should also work.
\section1 CMake Projects
In CMake, libaries are usually detected using the \c{FIND_PACKAGE()} macro.
A couple of them are already being shipped with CMake, they can be found in
the \c{Modules} directory of your CMake installation. If you provide
libraries on your own, you will need to provide your own \c{FindFoo.cmake}
file. Refer to the \l{http://vtk.org/Wiki/CMake_FAQ#Writing_FindXXX.cmake_files}
{CMake FAQ} for details.
As with qmake project, syntax completion and highlighting should work if
you can sucessfully build and link against the external library.
\section1 Generic Projects
If you import a project using the \e{Generic Projects} function, Qt Creator will
create a file called \c{<projectname>.includes} in your project root directory. It will
contain all project subdirectories it that was able to find relevant header files in.
Simply add your include pathes there.
Note that in Generic Project mode, Qt Creator will refrain from touching any
project settings, so the above is merely a hint for the code completion and
the syntax highlighter.
*/
/*!
\contentspage index.html
\previouspage creator-debugging.html
\previouspage creator-external-library-handling.html
\page creator-tips.html
\nextpage creator-keyboard-shortcuts.html
......@@ -1734,4 +1789,3 @@
QtCreator/src/shared/cplusplus
\endlist
*/
......@@ -69,7 +69,7 @@ SaveItemsDialog::SaveItemsDialog(QWidget *parent,
visibleName = info.fileName();
}
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.treeWidget, QStringList()
<< visibleName << directory);
<< visibleName << QDir::toNativeSeparators(directory));
item->setData(0, Qt::UserRole, qVariantFromValue(file));
}
......
......@@ -312,6 +312,8 @@ StartRemoteDialog::StartRemoteDialog(QWidget *parent)
{
m_ui->setupUi(this);
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
m_ui->serverStartScript->setExpectedKind(Core::Utils::PathChooser::File);
m_ui->serverStartScript->setPromptDialogTitle(tr("Select Executable"));
connect(m_ui->buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
connect(m_ui->buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
......@@ -354,6 +356,15 @@ QString StartRemoteDialog::remoteArchitecture() const
return m_ui->architectureComboBox->itemText(index);
}
void StartRemoteDialog::setServerStartScript(const QString &scriptName)
{
m_ui->serverStartScript->setPath(scriptName);
}
QString StartRemoteDialog::serverStartScript() const
{
return m_ui->serverStartScript->path();
}
///////////////////////////////////////////////////////////////////////
//
......
......@@ -114,6 +114,8 @@ public:
void setRemoteArchitectures(const QStringList &arches);
QString remoteChannel() const;
QString remoteArchitecture() const;
void setServerStartScript(const QString &scriptName);
QString serverStartScript() const;
private:
Ui::StartRemoteDialog *m_ui;
......
......@@ -936,14 +936,17 @@ void DebuggerManager::startNewDebugger(DebuggerRunControl *runControl)
dlg.setRemoteArchitectures(arches);
dlg.setRemoteChannel(configValue(_("LastRemoteChannel")).toString());
dlg.setRemoteArchitecture(configValue(_("LastRemoteArchtecture")).toString());
dlg.setServerStartScript(configValue(_("LastServerStartScript")).toString());
if (dlg.exec() != QDialog::Accepted) {
runControl->debuggingFinished();
return;
}
setConfigValue(_("LastRemoteChannel"), dlg.remoteChannel());
setConfigValue(_("LastRemoteArchitecture"), dlg.remoteArchitecture());
setConfigValue(_("LastServerStartScript"), dlg.serverStartScript());
m_remoteChannel = dlg.remoteChannel();
m_remoteArchitecture = dlg.remoteArchitecture();
m_serverStartScript = dlg.serverStartScript();
break;
}
}
......
......@@ -359,8 +359,10 @@ public:
QString m_dumperLib;
int m_attachedPID;
bool m_useTerminal;
// for remote debugging
QString m_remoteChannel;
QString m_remoteArchitecture;
QString m_serverStartScript;
private:
void init();
......
......@@ -131,22 +131,28 @@ GdbEngine::~GdbEngine()
void GdbEngine::initializeConnections()
{
// Gdb Process interaction
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)), this,
SLOT(gdbProcError(QProcess::ProcessError)));
connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()), this,
SLOT(readGdbStandardOutput()));
connect(&m_gdbProc, SIGNAL(readyReadStandardError()), this,
SLOT(readGdbStandardError()));
connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)), q,
SLOT(exitDebugger()));
connect(&m_stubProc, SIGNAL(processError(QString)), SLOT(stubError(QString)));
connect(&m_stubProc, SIGNAL(processStarted()), SLOT(stubStarted()));
connect(&m_stubProc, SIGNAL(wrapperStopped()), q, SLOT(exitDebugger()));
connect(&m_gdbProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(gdbProcError(QProcess::ProcessError)));
connect(&m_gdbProc, SIGNAL(readyReadStandardOutput()),
this, SLOT(readGdbStandardOutput()));
connect(&m_gdbProc, SIGNAL(readyReadStandardError()),
this, SLOT(readGdbStandardError()));
connect(&m_gdbProc, SIGNAL(finished(int, QProcess::ExitStatus)),
q, SLOT(exitDebugger()));
connect(&m_stubProc, SIGNAL(processError(QString)),
this, SLOT(stubError(QString)));
connect(&m_stubProc, SIGNAL(processStarted()),
this, SLOT(stubStarted()));
connect(&m_stubProc, SIGNAL(wrapperStopped()),
q, SLOT(exitDebugger()));
connect(&m_uploadProc, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(uploadProcError(QProcess::ProcessError)));
// Output
connect(&m_outputCollector, SIGNAL(byteDelivery(QByteArray)),
SLOT(readDebugeeOutput(QByteArray)));
this, SLOT(readDebugeeOutput(QByteArray)));
connect(this, SIGNAL(gdbOutputAvailable(QString,QString)),
q, SLOT(showDebuggerOutput(QString,QString)),
......@@ -225,6 +231,43 @@ void GdbEngine::gdbProcError(QProcess::ProcessError error)
q->exitDebugger();
}
void GdbEngine::uploadProcError(QProcess::ProcessError error)
{
QString msg;
switch (error) {
case QProcess::FailedToStart:
msg = tr("The upload process failed to start. Either the "
"invoked script '%1' is missing, or you may have insufficient "
"permissions to invoke the program.")
.arg(theDebuggerStringSetting(GdbLocation));
break;
case QProcess::Crashed:
msg = tr("The upload process crashed some time after starting "
"successfully.");
break;
case QProcess::Timedout:
msg = tr("The last waitFor...() function timed out. "
"The state of QProcess is unchanged, and you can try calling "
"waitFor...() again.");
break;
case QProcess::WriteError:
msg = tr("An error occurred when attempting to write "
"to the upload process. For example, the process may not be running, "
"or it may have closed its input channel.");
break;
case QProcess::ReadError:
msg = tr("An error occurred when attempting to read from "
"the upload process. For example, the process may not be running.");
break;
default:
msg = tr("An unknown error in the upload process occurred. "
"This is the default return value of error().");
}
q->showStatusMessage(msg);
QMessageBox::critical(q->mainWindow(), tr("Error"), msg);
}
#if 0
static void dump(const char *first, const char *middle, const QString & to)
{
......@@ -907,6 +950,7 @@ void GdbEngine::handleAqcuiredInferior()
#endif
if (theDebuggerBoolSetting(ListSourceFiles))
reloadSourceFiles();
tryLoadDebuggingHelpers();
#ifndef Q_OS_MAC
......@@ -1358,7 +1402,18 @@ bool GdbEngine::startDebugger()
if (q->startMode() == AttachCore || q->startMode() == AttachExternal) {
// nothing to do
} else if (q->startMode() == StartRemote) {
// nothing to do
// Start the remote server
if (q->m_serverStartScript.isEmpty()) {
q->showStatusMessage(_("No server start script given. "
"Assuming server runs already."));
} else {
if (!q->m_workingDir.isEmpty())
m_uploadProc.setWorkingDirectory(q->m_workingDir);
if (!q->m_environment.isEmpty())
m_uploadProc.setEnvironment(q->m_environment);
m_uploadProc.start(_("/bin/sh ") + q->m_serverStartScript);
m_uploadProc.waitForStarted();
}
} else if (q->m_useTerminal) {
m_stubProc.stop(); // We leave the console open, so recycle it now.
......@@ -2795,7 +2850,7 @@ bool GdbEngine::hasDebuggingHelperForType(const QString &type) const
if (!theDebuggerBoolSetting(UseDebuggingHelpers))
return false;
if (q->startMode() == AttachCore) {
if (!startModeAllowsDumpers()) {
// "call" is not possible in gdb when looking at core files
return type == __("QString") || type.endsWith(__("::QString"))
|| type == __("QStringList") || type.endsWith(__("::QStringList"));
......@@ -2834,7 +2889,7 @@ void GdbEngine::runDirectDebuggingHelper(const WatchData &data, bool dumpChildre
void GdbEngine::runDebuggingHelper(const WatchData &data0, bool dumpChildren)
{
if (q->startMode() == AttachCore) {
if (!startModeAllowsDumpers()) {
runDirectDebuggingHelper(data0, dumpChildren);
return;
}
......@@ -3832,6 +3887,9 @@ void GdbEngine::tryLoadDebuggingHelpers()
if (m_debuggingHelperState != DebuggingHelperUninitialized)
return;
if (!startModeAllowsDumpers())
return;
PENDING_DEBUG("TRY LOAD CUSTOM DUMPERS");
m_debuggingHelperState = DebuggingHelperUnavailable;
if (!qq->qtDumperLibraryEnabled())
......@@ -3881,9 +3939,18 @@ void GdbEngine::tryLoadDebuggingHelpers()
void GdbEngine::recheckDebuggingHelperAvailability()
{
// retreive list of dumpable classes
execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"));
execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
if (startModeAllowsDumpers()) {
// retreive list of dumpable classes
execCommand(_("call (void*)qDumpObjectData440(1,%1+1,0,0,0,0,0,0)"));
execCommand(_("p (char*)&qDumpOutBuffer"), CB(handleQueryDebuggingHelper));
}
}
bool GdbEngine::startModeAllowsDumpers() const
{
return q->startMode() == StartInternal
|| q->startMode() == StartExternal
|| q->startMode() == AttachExternal;
}
IDebuggerEngine *createGdbEngine(DebuggerManager *parent, QList<Core::IOptionsPage*> *opts)
......
......@@ -191,6 +191,7 @@ private slots:
void readDebugeeOutput(const QByteArray &data);
void stubStarted();
void stubError(const QString &msg);
void uploadProcError(QProcess::ProcessError error);
private:
int terminationIndex(const QByteArray &buffer, int &length);
......@@ -226,6 +227,7 @@ private:
QByteArray m_inbuffer;
QProcess m_gdbProc;
QProcess m_uploadProc;
Core::Utils::ConsoleProcess m_stubProc;
......@@ -354,6 +356,8 @@ private:
const WatchData &parent);
void setWatchDataType(WatchData &data, const GdbMi &mi);
void setLocals(const QList<GdbMi> &locals);
bool startModeAllowsDumpers() const;
QString m_editedData;
int m_pendingRequests;
......
......@@ -49,6 +49,16 @@
<item row="1" column="1">
<widget class="QComboBox" name="architectureComboBox"/>
</item>
<item row="2" column="0">
<widget class="QLabel" name="serverStartScriptLabel">
<property name="text">
<string>Server start script</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Core::Utils::PathChooser" name="serverStartScript" native="true"/>
</item>
</layout>
</item>
<item>
......
#!/bin/sh
account=berlin@hd
sourcedir=/data5/dev/creator/tests/manual/fakevim/
exename=fakevim
targetdir=/tmp/run-${exename}
executable=${sourcedir}/${exename}
qtlibs=`ldd ${executable} | grep libQt | sed -e 's/^.*=> \(.*\) (.*)$/\1/'`
ssh ${account} "mkdir -p ${targetdir}"
scp ${executable} ${qtlibs} ${account}:${targetdir}
ssh ${account} "chrpath -r ${targetdir} ${targetdir}/*"
ssh ${account} "gdbserver localhost:5555 ${targetdir}/${exename}"
ssh ${account} "rm ${targetdir}/* ; rmdir ${targetdir}"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment