Debugging helpers: Fix building

- Report errors correctly.
- Do not pass empty target argument to qmake
- Give 'make' a longer timeout and change timeout checking to
  trigger after last output line was obtained from process
- Make build log dialog non-modal and ensure it pops up on failure
  even if a different Qt version was selected in-between
- Disable Rebuild-button while build is running.

Reviewed-by: Kai Köhne <kai.koehne@nokia.com>
Reviewed-by: Lasse Holmstedt <lasse.holmstedt@nokia.com>
This commit is contained in:
Friedemann Kleint
2010-10-08 15:13:02 +02:00
parent f6a1e3b388
commit f5909abe09
13 changed files with 260 additions and 132 deletions

View File

@@ -171,12 +171,79 @@ bool BuildableHelperLibrary::copyFiles(const QString &sourcePath,
return true; return true;
} }
QString BuildableHelperLibrary::buildHelper(const QString &helperName, const QString &proFilename, // Helper: Run a build process with merged stdout/stderr
const QString &directory, const QString &makeCommand, static inline bool runBuildProcessI(QProcess &proc,
const QString &qmakeCommand, const QString &mkspec, const QString &binary,
const Utils::Environment &env, const QString &targetMode) const QStringList &args,
int timeoutMS,
bool ignoreNonNullExitCode,
QString *output, QString *errorMessage)
{
proc.start(binary, args);
if (!proc.waitForStarted()) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
"Cannot start process: %1").
arg(proc.errorString());
return false;
}
// Read stdout/err and check for timeouts
QByteArray stdOut;
QByteArray stdErr;
if (!SynchronousProcess::readDataFromProcess(proc, timeoutMS, &stdOut, &stdErr, false)) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
"Timeout after %1s.").
arg(timeoutMS / 1000);
SynchronousProcess::stopProcess(proc);
return false;
}
if (proc.exitStatus() != QProcess::NormalExit) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
"The process crashed.");
return false;
}
const QString stdOutS = QString::fromLocal8Bit(stdOut);
if (!ignoreNonNullExitCode && proc.exitCode() != 0) {
*errorMessage = QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
"The process returned exit code %1:\n%2").
arg(proc.exitCode()).arg(stdOutS);
return false;
}
output->append(stdOutS);
return true;
}
// Run a build process with merged stdout/stderr and qWarn about errors.
static bool runBuildProcess(QProcess &proc,
const QString &binary,
const QStringList &args,
int timeoutMS,
bool ignoreNonNullExitCode,
QString *output, QString *errorMessage)
{
const bool rc = runBuildProcessI(proc, binary, args, timeoutMS, ignoreNonNullExitCode, output, errorMessage);
if (!rc) {
// Fail - reformat error.
QString cmd = binary;
if (!args.isEmpty()) {
cmd += QLatin1Char(' ');
cmd += args.join(QString(QLatin1Char(' ')));
}
*errorMessage =
QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
"Error running '%1' in %2: %3").
arg(cmd, proc.workingDirectory(), *errorMessage);
qWarning("%s", qPrintable(*errorMessage));
}
return rc;
}
bool BuildableHelperLibrary::buildHelper(const QString &helperName, const QString &proFilename,
const QString &directory, const QString &makeCommand,
const QString &qmakeCommand, const QString &mkspec,
const Utils::Environment &env, const QString &targetMode,
QString *output, QString *errorMessage)
{ {
QString output;
const QChar newline = QLatin1Char('\n'); const QChar newline = QLatin1Char('\n');
// Setup process // Setup process
QProcess proc; QProcess proc;
@@ -184,45 +251,43 @@ QString BuildableHelperLibrary::buildHelper(const QString &helperName, const QSt
proc.setWorkingDirectory(directory); proc.setWorkingDirectory(directory);
proc.setProcessChannelMode(QProcess::MergedChannels); proc.setProcessChannelMode(QProcess::MergedChannels);
output += QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary", output->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
"Building helper library '%1' in %2\n").arg(helperName, directory); "Building helper library '%1' in %2\n").arg(helperName, directory));
output += newline; output->append(newline);
const QString makeFullPath = env.searchInPath(makeCommand); const QString makeFullPath = env.searchInPath(makeCommand);
if (QFileInfo(directory + QLatin1String("/Makefile")).exists()) { if (QFileInfo(directory + QLatin1String("/Makefile")).exists()) {
if (!makeFullPath.isEmpty()) { if (makeFullPath.isEmpty()) {
const QString cleanTarget = QLatin1String("distclean"); *errorMessage = QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary",
output += QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary", "%1 not found in PATH\n").arg(makeCommand);
"Running %1 %2...\n").arg(makeFullPath, cleanTarget); return false;
proc.start(makeFullPath, QStringList(cleanTarget));
proc.waitForFinished();
output += QString::fromLocal8Bit(proc.readAll());
} else {
output += QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary",
"%1 not found in PATH\n").arg(makeCommand);
return output;
} }
const QString cleanTarget = QLatin1String("distclean");
output->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary",
"Running %1 %2...\n").arg(makeFullPath, cleanTarget));
if (!runBuildProcess(proc, makeFullPath, QStringList(cleanTarget), 30000, true, output, errorMessage))
return false;
} }
output += newline; output->append(newline);
output += QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary", "Running %1 ...\n").arg(qmakeCommand); output->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary", "Running %1 ...\n").arg(qmakeCommand));
QStringList makeArgs; QStringList qMakeArgs;
makeArgs << targetMode << QLatin1String("-spec") << (mkspec.isEmpty() ? QString(QLatin1String("default")) : mkspec) << proFilename; if (!targetMode.isEmpty())
proc.start(qmakeCommand, makeArgs); qMakeArgs << targetMode;
proc.waitForFinished(); if (!mkspec.isEmpty())
qMakeArgs << QLatin1String("-spec") << mkspec;
output += proc.readAll(); qMakeArgs << proFilename;
if (!runBuildProcess(proc, qmakeCommand, qMakeArgs, 30000, false, output, errorMessage))
output += newline;; return false;
if (!makeFullPath.isEmpty()) { output->append(newline);
output += QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary", "Running %1 ...\n").arg(makeFullPath); if (makeFullPath.isEmpty()) {
proc.start(makeFullPath, QStringList()); *errorMessage = QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary", "%1 not found in PATH\n").arg(makeCommand);
proc.waitForFinished(80000); return false;
output += proc.readAll();
} else {
output += QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary", "%1 not found in PATH\n").arg(makeCommand);
} }
return output; output->append(QCoreApplication::translate("ProjectExplorer::BuildableHelperLibrary", "Running %1 ...\n").arg(makeFullPath));
if (!runBuildProcess(proc, makeFullPath, QStringList(), 120000, false, output, errorMessage))
return false;
return true;
} }
bool BuildableHelperLibrary::getHelperFileInfoFor(const QStringList &validBinaryFilenames, bool BuildableHelperLibrary::getHelperFileInfoFor(const QStringList &validBinaryFilenames,

View File

@@ -33,10 +33,11 @@ public:
static bool copyFiles(const QString &sourcePath, const QStringList &files, static bool copyFiles(const QString &sourcePath, const QStringList &files,
const QString &targetDirectory, QString *errorMessage); const QString &targetDirectory, QString *errorMessage);
static QString buildHelper(const QString &helperName, const QString &proFilename, static bool buildHelper(const QString &helperName, const QString &proFilename,
const QString &directory, const QString &makeCommand, const QString &directory, const QString &makeCommand,
const QString &qmakeCommand, const QString &mkspec, const QString &qmakeCommand, const QString &mkspec,
const Utils::Environment &env, const QString &targetMode); const Utils::Environment &env, const QString &targetMode,
QString *output, QString *errorMessage);
static bool getHelperFileInfoFor(const QStringList &validBinaryFilenames, static bool getHelperFileInfoFor(const QStringList &validBinaryFilenames,
const QString &directory, QFileInfo* info); const QString &directory, QFileInfo* info);

View File

@@ -116,11 +116,12 @@ QString DebuggingHelperLibrary::copy(const QString &qtInstallData,
return QString(); return QString();
} }
QString DebuggingHelperLibrary::build(const QString &directory, const QString &makeCommand, bool DebuggingHelperLibrary::build(const QString &directory, const QString &makeCommand,
const QString &qmakeCommand, const QString &mkspec, const QString &qmakeCommand, const QString &mkspec,
const Utils::Environment &env, const QString &targetMode) const Utils::Environment &env, const QString &targetMode,
QString *output, QString *errorMessage)
{ {
return buildHelper(QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary", return buildHelper(QCoreApplication::translate("ProjectExplorer::DebuggingHelperLibrary",
"GDB helper"), QLatin1String("gdbmacros.pro"), directory, "GDB helper"), QLatin1String("gdbmacros.pro"), directory,
makeCommand, qmakeCommand, mkspec, env, targetMode); makeCommand, qmakeCommand, mkspec, env, targetMode, output, errorMessage);
} }

View File

@@ -47,9 +47,10 @@ public:
static QStringList locationsByInstallData(const QString &qtInstallData); static QStringList locationsByInstallData(const QString &qtInstallData);
// Build the helpers and return the output log/errormessage. // Build the helpers and return the output log/errormessage.
static QString build(const QString &directory, const QString &makeCommand, static bool build(const QString &directory, const QString &makeCommand,
const QString &qmakeCommand, const QString &mkspec, const QString &qmakeCommand, const QString &mkspec,
const Utils::Environment &env, const QString &targetMode); const Utils::Environment &env, const QString &targetMode,
QString *output, QString *errorMessage);
// Copy the source files to a target location and return the chosen target location. // Copy the source files to a target location and return the chosen target location.
static QString copy(const QString &qtInstallData, QString *errorMessage); static QString copy(const QString &qtInstallData, QString *errorMessage);

View File

@@ -70,14 +70,19 @@ public:
{ {
future.setProgressRange(0, 5); future.setProgressRange(0, 5);
future.setProgressValue(1); future.setProgressValue(1);
const QString output = m_version.buildDebuggingHelperLibrary(future, true); QString output;
QString errorMessage;
const QString qtInstallData = m_version.versionInfo().value("QT_INSTALL_DATA"); QString path;
QString path = QmlDumpTool::toolByInstallData(qtInstallData); if (m_version.buildDebuggingHelperLibrary(future, true, &output, &errorMessage)) {
if (path.isEmpty()) { const QString qtInstallData = m_version.versionInfo().value("QT_INSTALL_DATA");
qWarning() << "Could not build QML plugin dumping helper for " << m_version.displayName() path = QmlDumpTool::toolByInstallData(qtInstallData);
<< "\nOutput:\n" << output; if (path.isEmpty())
m_failed = true; errorMessage = QString::fromLatin1("Could not build QML plugin dumping helper for %1\nOutput:\n%2").
arg(m_version.displayName(), output);
}
m_failed = path.isEmpty();
if (m_failed) {
qWarning("%s", qPrintable(errorMessage));
} else { } else {
// proceed in gui thread // proceed in gui thread
metaObject()->invokeMethod(this, "finish", Qt::QueuedConnection, Q_ARG(QString, path)); metaObject()->invokeMethod(this, "finish", Qt::QueuedConnection, Q_ARG(QString, path));
@@ -222,12 +227,14 @@ QStringList QmlDumpTool::locationsByInstallData(const QString &qtInstallData)
return result; return result;
} }
QString QmlDumpTool::build(const QString &directory, const QString &makeCommand, bool QmlDumpTool::build(const QString &directory, const QString &makeCommand,
const QString &qmakeCommand, const QString &mkspec, const QString &qmakeCommand, const QString &mkspec,
const Utils::Environment &env, const QString &targetMode) const Utils::Environment &env, const QString &targetMode,
QString *output, QString *errorMessage)
{ {
return buildHelper(QCoreApplication::translate("Qt4ProjectManager::QmlDumpTool", "qmldump"), QLatin1String("qmldump.pro"), return buildHelper(QCoreApplication::translate("Qt4ProjectManager::QmlDumpTool", "qmldump"), QLatin1String("qmldump.pro"),
directory, makeCommand, qmakeCommand, mkspec, env, targetMode); directory, makeCommand, qmakeCommand, mkspec, env, targetMode,
output, errorMessage);
} }
QString QmlDumpTool::copy(const QString &qtInstallData, QString *errorMessage) QString QmlDumpTool::copy(const QString &qtInstallData, QString *errorMessage)

View File

@@ -53,9 +53,10 @@ public:
static QStringList locationsByInstallData(const QString &qtInstallData); static QStringList locationsByInstallData(const QString &qtInstallData);
// Build the helpers and return the output log/errormessage. // Build the helpers and return the output log/errormessage.
static QString build(const QString &directory, const QString &makeCommand, static bool build(const QString &directory, const QString &makeCommand,
const QString &qmakeCommand, const QString &mkspec, const QString &qmakeCommand, const QString &mkspec,
const Utils::Environment &env, const QString &targetMode); const Utils::Environment &env, const QString &targetMode,
QString *output, QString *errorMessage);
// Copy the source files to a target location and return the chosen target location. // Copy the source files to a target location and return the chosen target location.
static QString copy(const QString &qtInstallData, QString *errorMessage); static QString copy(const QString &qtInstallData, QString *errorMessage);

View File

@@ -99,13 +99,15 @@ QStringList QmlObserverTool::locationsByInstallData(const QString &qtInstallData
return result; return result;
} }
QString QmlObserverTool::build(const QString &directory, const QString &makeCommand, bool QmlObserverTool::build(const QString &directory, const QString &makeCommand,
const QString &qmakeCommand, const QString &mkspec, const QString &qmakeCommand, const QString &mkspec,
const Utils::Environment &env, const QString &targetMode) const Utils::Environment &env, const QString &targetMode,
QString *output, QString *errorMessage)
{ {
return buildHelper(QCoreApplication::translate("Qt4ProjectManager::QmlObserverTool", "QMLObserver"), return buildHelper(QCoreApplication::translate("Qt4ProjectManager::QmlObserverTool", "QMLObserver"),
QLatin1String("qmlobserver.pro"), QLatin1String("qmlobserver.pro"),
directory, makeCommand, qmakeCommand, mkspec, env, targetMode); directory, makeCommand, qmakeCommand, mkspec, env, targetMode,
output, errorMessage);
} }
static inline bool mkpath(const QString &targetDirectory, QString *errorMessage) static inline bool mkpath(const QString &targetDirectory, QString *errorMessage)

View File

@@ -54,9 +54,10 @@ public:
static QStringList locationsByInstallData(const QString &qtInstallData); static QStringList locationsByInstallData(const QString &qtInstallData);
// Build the helpers and return the output log/errormessage. // Build the helpers and return the output log/errormessage.
static QString build(const QString &directory, const QString &makeCommand, static bool build(const QString &directory, const QString &makeCommand,
const QString &qmakeCommand, const QString &mkspec, const QString &qmakeCommand, const QString &mkspec,
const Utils::Environment &env, const QString &targetMode); const Utils::Environment &env, const QString &targetMode,
QString *output, QString *errorMessage);
// Copy the source files to a target location and return the chosen target location. // Copy the source files to a target location and return the chosen target location.
static QString copy(const QString &qtInstallData, QString *errorMessage); static QString copy(const QString &qtInstallData, QString *errorMessage);

View File

@@ -54,6 +54,8 @@
#include <QtGui/QHelpEvent> #include <QtGui/QHelpEvent>
#include <QtGui/QToolTip> #include <QtGui/QToolTip>
enum ModelRoles { BuildLogRole = Qt::UserRole, BuildRunningRole = Qt::UserRole + 1 };
using namespace Qt4ProjectManager; using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal; using namespace Qt4ProjectManager::Internal;
@@ -74,8 +76,14 @@ void DebuggingHelperBuildTask::run(QFutureInterface<void> &future)
{ {
future.setProgressRange(0, 5); future.setProgressRange(0, 5);
future.setProgressValue(1); future.setProgressValue(1);
const QString output = m_version->buildDebuggingHelperLibrary(future); QString output;
emit finished(m_version->displayName(), output); QString errorMessage;
if (m_version->buildDebuggingHelperLibrary(future, false, &output, &errorMessage)) {
emit finished(m_version->displayName(), output);
} else {
qWarning("%s", qPrintable(errorMessage));
emit finished(m_version->displayName(), errorMessage);
}
deleteLater(); deleteLater();
} }
@@ -232,7 +240,7 @@ QtOptionsPageWidget::QtOptionsPageWidget(QWidget *parent, QList<QtVersion *> ver
connect(m_ui->rebuildButton, SIGNAL(clicked()), connect(m_ui->rebuildButton, SIGNAL(clicked()),
this, SLOT(buildDebuggingHelper())); this, SLOT(buildDebuggingHelper()));
connect(m_ui->showLogButton, SIGNAL(clicked()), connect(m_ui->showLogButton, SIGNAL(clicked()),
this, SLOT(showDebuggingBuildLog())); this, SLOT(slotShowDebuggingBuildLog()));
showEnvironmentPage(0); showEnvironmentPage(0);
updateState(); updateState();
@@ -315,7 +323,9 @@ void QtOptionsPageWidget::debuggingHelperBuildFinished(const QString &name, cons
// Update item view // Update item view
QTreeWidgetItem *item = treeItemForIndex(index); QTreeWidgetItem *item = treeItemForIndex(index);
QTC_ASSERT(item, return) QTC_ASSERT(item, return)
item->setData(2, Qt::UserRole, output); item->setData(2, BuildRunningRole, QVariant(false));
item->setData(2, BuildLogRole, output);
QSharedPointerQtVersion qtVersion = m_versions.at(index); QSharedPointerQtVersion qtVersion = m_versions.at(index);
const bool success = qtVersion->hasDebuggingHelper() const bool success = qtVersion->hasDebuggingHelper()
&& (!QmlDumpTool::canBuild(qtVersion.data()) || qtVersion->hasQmlDump()) && (!QmlDumpTool::canBuild(qtVersion.data()) || qtVersion->hasQmlDump())
@@ -325,10 +335,11 @@ void QtOptionsPageWidget::debuggingHelperBuildFinished(const QString &name, cons
// Update bottom control if the selection is still the same // Update bottom control if the selection is still the same
if (index == currentIndex()) { if (index == currentIndex()) {
m_ui->showLogButton->setEnabled(true); m_ui->showLogButton->setEnabled(true);
m_ui->rebuildButton->setEnabled(true);
updateDebuggingHelperStateLabel(m_versions.at(index).data()); updateDebuggingHelperStateLabel(m_versions.at(index).data());
if (!success)
showDebuggingBuildLog();
} }
if (!success)
showDebuggingBuildLog(item);
} }
void QtOptionsPageWidget::buildDebuggingHelper() void QtOptionsPageWidget::buildDebuggingHelper()
@@ -337,7 +348,12 @@ void QtOptionsPageWidget::buildDebuggingHelper()
if (index < 0) if (index < 0)
return; return;
QTreeWidgetItem *item = treeItemForIndex(index);
QTC_ASSERT(item, return);
m_ui->showLogButton->setEnabled(false); m_ui->showLogButton->setEnabled(false);
m_ui->rebuildButton->setEnabled(false);
item->setData(2, BuildRunningRole, QVariant(true));
// Run a debugging helper build task in the background. // Run a debugging helper build task in the background.
DebuggingHelperBuildTask *buildTask = new DebuggingHelperBuildTask(m_versions.at(index)); DebuggingHelperBuildTask *buildTask = new DebuggingHelperBuildTask(m_versions.at(index));
connect(buildTask, SIGNAL(finished(QString,QString)), this, SLOT(debuggingHelperBuildFinished(QString,QString)), connect(buildTask, SIGNAL(finished(QString,QString)), this, SLOT(debuggingHelperBuildFinished(QString,QString)),
@@ -348,21 +364,44 @@ void QtOptionsPageWidget::buildDebuggingHelper()
QLatin1String("Qt4ProjectManager::BuildHelpers")); QLatin1String("Qt4ProjectManager::BuildHelpers"));
} }
void QtOptionsPageWidget::showDebuggingBuildLog() // Non-modal dialog
{ class BuildLogDialog : public QDialog {
QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem(); public:
explicit BuildLogDialog(QWidget *parent = 0);
void setText(const QString &text);
int currentItemIndex = indexForTreeItem(currentItem); private:
Ui_ShowBuildLog m_ui;
};
BuildLogDialog::BuildLogDialog(QWidget *parent) : QDialog(parent)
{
m_ui.setupUi(this);
setAttribute(Qt::WA_DeleteOnClose, true);
}
void BuildLogDialog::setText(const QString &text)
{
m_ui.log->setPlainText(text); // Show and scroll to bottom
m_ui.log->moveCursor(QTextCursor::End);
m_ui.log->ensureCursorVisible();
}
void QtOptionsPageWidget::slotShowDebuggingBuildLog()
{
if (const QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem())
showDebuggingBuildLog(currentItem);
}
void QtOptionsPageWidget::showDebuggingBuildLog(const QTreeWidgetItem *currentItem)
{
const int currentItemIndex = indexForTreeItem(currentItem);
if (currentItemIndex < 0) if (currentItemIndex < 0)
return; return;
// Show and scroll to bottom BuildLogDialog *dialog = new BuildLogDialog(this);
QDialog dlg(this); dialog->setWindowTitle(tr("Debugging Helper Build Log for '%1'").arg(currentItem->text(0)));
Ui_ShowBuildLog ui; dialog->setText(currentItem->data(2, BuildLogRole).toString());
ui.setupUi(&dlg); dialog->show();
ui.log->setPlainText(currentItem->data(2, Qt::UserRole).toString());
ui.log->moveCursor(QTextCursor::End);
ui.log->ensureCursorVisible();
dlg.exec();
} }
QtOptionsPageWidget::~QtOptionsPageWidget() QtOptionsPageWidget::~QtOptionsPageWidget()
@@ -472,10 +511,11 @@ void QtOptionsPageWidget::updateState()
m_ui->s60SDKPath->setEnabled(s60SDKPathEnabled); m_ui->s60SDKPath->setEnabled(s60SDKPathEnabled);
m_ui->gccePath->setEnabled(enabled); m_ui->gccePath->setEnabled(enabled);
const bool hasLog = enabled && !m_ui->qtdirList->currentItem()->data(2, Qt::UserRole).toString().isEmpty(); const QTreeWidgetItem *currentItem = m_ui->qtdirList->currentItem();
const bool buildRunning = currentItem && currentItem->data(2, BuildRunningRole).toBool();
const bool hasLog = enabled && currentItem && !currentItem->data(2, Qt::UserRole).toString().isEmpty();
m_ui->showLogButton->setEnabled(hasLog); m_ui->showLogButton->setEnabled(hasLog);
m_ui->rebuildButton->setEnabled(version && version->isValid() && !buildRunning);
m_ui->rebuildButton->setEnabled(version && version->isValid());
updateDebuggingHelperStateLabel(version); updateDebuggingHelperStateLabel(version);
} }
@@ -638,6 +678,7 @@ void QtOptionsPageWidget::versionChanged(QTreeWidgetItem *item, QTreeWidgetItem
} else { } else {
m_ui->nameEdit->clear(); m_ui->nameEdit->clear();
m_ui->qmakePath->setPath(QString()); // clear() m_ui->qmakePath->setPath(QString()); // clear()
} }
showEnvironmentPage(item); showEnvironmentPage(item);
updateState(); updateState();

View File

@@ -125,8 +125,11 @@ private slots:
void updateCurrentGcceDirectory(); void updateCurrentGcceDirectory();
void msvcVersionChanged(); void msvcVersionChanged();
void buildDebuggingHelper(); void buildDebuggingHelper();
void showDebuggingBuildLog(); void slotShowDebuggingBuildLog();
void debuggingHelperBuildFinished(const QString &versionName, const QString &output); void debuggingHelperBuildFinished(const QString &versionName, const QString &output);
private:
void showDebuggingBuildLog(const QTreeWidgetItem *currentItem);
}; };
class QtOptionsPage : public Core::IOptionsPage class QtOptionsPage : public Core::IOptionsPage

View File

@@ -1757,66 +1757,70 @@ bool QtVersion::isQt64Bit() const
#endif #endif
} }
QString QtVersion::buildDebuggingHelperLibrary(QFutureInterface<void> &future, bool onlyQmlDump) bool QtVersion::buildDebuggingHelperLibrary(QFutureInterface<void> &future,
bool onlyQmlDump,
QString *output, QString *errorMessage)
{ {
QString qtInstallHeaders = versionInfo().value("QT_INSTALL_HEADERS"); const QString qtInstallData = versionInfo().value("QT_INSTALL_DATA");
QString qtInstallData = versionInfo().value("QT_INSTALL_DATA"); if (qtInstallData.isEmpty()) {
if (qtInstallData.isEmpty()) *errorMessage =
return QString(); QCoreApplication::translate("QtVersion",
"Cannot determine the installation path for Qt version '%1'.").
arg(displayName());
return false;
}
Utils::Environment env = Utils::Environment::systemEnvironment(); Utils::Environment env = Utils::Environment::systemEnvironment();
addToEnvironment(env); addToEnvironment(env);
// TODO: the debugging helper doesn't comply to actual tool chain yet // TODO: the debugging helper doesn't comply to actual tool chain yet
QList<QSharedPointer<ProjectExplorer::ToolChain> > alltc = toolChains(); QList<QSharedPointer<ProjectExplorer::ToolChain> > alltc = toolChains();
ProjectExplorer::ToolChain *tc = alltc.isEmpty() ? 0 : alltc.first().data(); ProjectExplorer::ToolChain *tc = alltc.isEmpty() ? 0 : alltc.first().data();
if (!tc) if (!tc) {
return QCoreApplication::translate("QtVersion", "The Qt Version has no toolchain."); *errorMessage = QCoreApplication::translate("QtVersion", "The Qt Version has no toolchain.");
return false;
}
tc->addToEnvironment(env); tc->addToEnvironment(env);
QString output; const QString target = (tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String(""));
// invalidate cache
m_versionInfoUpToDate = false;
if (!onlyQmlDump) { if (!onlyQmlDump) {
QString gdbHelperDirectory = DebuggingHelperLibrary::copy(qtInstallData, &output); const QString gdbHelperDirectory = DebuggingHelperLibrary::copy(qtInstallData, errorMessage);
if (!gdbHelperDirectory.isEmpty()) { if (gdbHelperDirectory.isEmpty())
output += DebuggingHelperLibrary::build(gdbHelperDirectory, tc->makeCommand(), return false;
qmakeCommand(), mkspec(), env, if (!DebuggingHelperLibrary::build(gdbHelperDirectory, tc->makeCommand(),
(tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String(""))); qmakeCommand(), mkspec(), env,
} target, output, errorMessage))
return false;
future.setProgressValue(2); future.setProgressValue(2);
if (QmlObserverTool::canBuild(this)) { if (QmlObserverTool::canBuild(this)) {
QString toolDirectory = QmlObserverTool::copy(qtInstallData, &output); const QString toolDirectory = QmlObserverTool::copy(qtInstallData, errorMessage);
if (!toolDirectory.isEmpty()) { if (toolDirectory.isEmpty())
output += QmlObserverTool::build(toolDirectory, tc->makeCommand(), return false;
qmakeCommand(), mkspec(), env, if (!QmlObserverTool::build(toolDirectory, tc->makeCommand(),
(tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String(""))); qmakeCommand(), mkspec(), env, target, output, errorMessage))
} return false;
} else { } else {
output += QCoreApplication::translate("Qt4ProjectManager::QtVersion", "Cannot build QMLObserver; Qt version must be 4.7.1 or higher."); output->append(QCoreApplication::translate("Qt4ProjectManager::QtVersion", "Warning: Cannot build QMLObserver; Qt version must be 4.7.1 or higher."));
} }
future.setProgressValue(3); future.setProgressValue(3);
} }
if (QmlDumpTool::canBuild(this)) { if (QmlDumpTool::canBuild(this)) {
QString toolDirectory = QmlDumpTool::copy(qtInstallData, &output); const QString qmlDumpToolDirectory = QmlDumpTool::copy(qtInstallData, errorMessage);
if (!toolDirectory.isEmpty()) { if (qmlDumpToolDirectory.isEmpty())
output += QmlDumpTool::build(toolDirectory, tc->makeCommand(), return false;
qmakeCommand(), mkspec(), env, if (!QmlDumpTool::build(qmlDumpToolDirectory, tc->makeCommand(),
(tc->type() == ToolChain::GCC_MAEMO ? QLatin1String("-unix") : QLatin1String(""))); qmakeCommand(), mkspec(), env, target, output, errorMessage))
} return false;
} else { } else {
output += QCoreApplication::translate("Qt4ProjectManager::QtVersion", "Cannot build qmldump; Qt version must be 4.7.1 or higher."); output->append(QCoreApplication::translate("Qt4ProjectManager::QtVersion", "Warning: Cannot build qmldump; Qt version must be 4.7.1 or higher."));
} }
future.setProgressValue(4); future.setProgressValue(4);
// invalidate version before updating version info return true;
m_versionInfoUpToDate = false;
updateVersionInfo();
if (!onlyQmlDump) {
m_hasDebuggingHelper = !debuggingHelperLibrary().isEmpty();
m_hasQmlObserver = !qmlObserverTool().isEmpty();
}
m_hasQmlDump = !qmlDumpTool().isEmpty();
return output;
} }

View File

@@ -122,7 +122,8 @@ public:
// Builds a debugging library // Builds a debugging library
// returns the output of the commands // returns the output of the commands
QString buildDebuggingHelperLibrary(QFutureInterface<void> &future, bool onlyQmlDump = false); bool buildDebuggingHelperLibrary(QFutureInterface<void> &future, bool onlyQmlDump,
QString *output, QString *errorMessage);
bool hasExamples() const; bool hasExamples() const;
QString examplesPath() const; QString examplesPath() const;

View File

@@ -30,7 +30,7 @@
<enum>Qt::Horizontal</enum> <enum>Qt::Horizontal</enum>
</property> </property>
<property name="standardButtons"> <property name="standardButtons">
<set>QDialogButtonBox::Ok</set> <set>QDialogButtonBox::Close</set>
</property> </property>
</widget> </widget>
</item> </item>