From b3ec859c80bd0656cfc48cfe6514ec4f631b8206 Mon Sep 17 00:00:00 2001 From: dt <qtc-committer@nokia.com> Date: Thu, 19 Mar 2009 15:04:43 +0100 Subject: [PATCH] Fixes: Handle debug and release scopes for TARGET and DESTDIR Task: 247606 Details: Remove all the magic which build on top of the cumalative parser. Instead trust the exact parsing to get those variables correct. This required a bug fix in the profile evaluator, done with ossi. Hopefully this doesn't break windows/mac. Will check. --- src/plugins/qt4projectmanager/qmakestep.cpp | 2 + .../qt4buildconfigwidget.cpp | 20 +- .../qt4projectmanager/qt4buildconfigwidget.h | 1 + src/plugins/qt4projectmanager/qt4project.cpp | 42 ++- src/plugins/qt4projectmanager/qt4project.h | 5 + .../qt4projectmanager/qt4runconfiguration.cpp | 241 ++++++------------ .../qt4projectmanager/qt4runconfiguration.h | 28 +- src/shared/proparser/profileevaluator.cpp | 23 +- src/shared/proparser/profileevaluator.h | 1 + 9 files changed, 185 insertions(+), 178 deletions(-) diff --git a/src/plugins/qt4projectmanager/qmakestep.cpp b/src/plugins/qt4projectmanager/qmakestep.cpp index 10190302624..b448f98e41d 100644 --- a/src/plugins/qt4projectmanager/qmakestep.cpp +++ b/src/plugins/qt4projectmanager/qmakestep.cpp @@ -234,6 +234,7 @@ void QMakeStepConfigWidget::qmakeArgumentsLineEditTextEdited() Q_ASSERT(!m_buildConfiguration.isNull()); m_step->setValue(m_buildConfiguration, "qmakeArgs", ProjectExplorer::Environment::parseCombinedArgString(m_ui.qmakeAdditonalArgumentsLineEdit->text())); m_ui.qmakeArgumentsEdit->setPlainText(ProjectExplorer::Environment::joinArgumentList(m_step->arguments(m_buildConfiguration))); + static_cast<Qt4Project *>(m_step->project())->invalidateCachedTargetInformation(); } void QMakeStepConfigWidget::buildConfigurationChanged() @@ -247,6 +248,7 @@ void QMakeStepConfigWidget::buildConfigurationChanged() } m_step->setValue(m_buildConfiguration, "buildConfiguration", int(buildConfiguration)); m_ui.qmakeArgumentsEdit->setPlainText(ProjectExplorer::Environment::joinArgumentList(m_step->arguments(m_buildConfiguration))); + static_cast<Qt4Project *>(m_step->project())->invalidateCachedTargetInformation(); } QString QMakeStepConfigWidget::displayName() const diff --git a/src/plugins/qt4projectmanager/qt4buildconfigwidget.cpp b/src/plugins/qt4projectmanager/qt4buildconfigwidget.cpp index c63861bc1fb..75fa4ee25c2 100644 --- a/src/plugins/qt4projectmanager/qt4buildconfigwidget.cpp +++ b/src/plugins/qt4projectmanager/qt4buildconfigwidget.cpp @@ -115,7 +115,7 @@ void Qt4BuildConfigWidget::init(const QString &buildConfiguration) m_ui->shadowBuildCheckBox->setChecked(shadowBuild); m_ui->shadowBuildDirEdit->setEnabled(shadowBuild); m_ui->shadowBuildDirEdit->setPath(m_pro->buildDirectory(buildConfiguration)); - shadowBuildLineEditTextChanged(); // Update the import label + updateImportLabel(); } void Qt4BuildConfigWidget::changeConfigName(const QString &newName) @@ -173,12 +173,8 @@ void Qt4BuildConfigWidget::shadowBuildCheckBoxClicked(bool checked) m_pro->setValue(m_buildConfiguration, "buildDirectory", QVariant(QString::null)); } -void Qt4BuildConfigWidget::shadowBuildLineEditTextChanged() +void Qt4BuildConfigWidget::updateImportLabel() { - m_pro->setValue(m_buildConfiguration, "buildDirectory", m_ui->shadowBuildDirEdit->path()); - // if the directory already exists - // check if we have a build in there and - // offer to import it m_ui->importLabel->setVisible(false); if (m_ui->shadowBuildCheckBox->isChecked()) { QString qtPath = m_pro->qt4ProjectManager()->versionManager()->findQtVersionFromMakefile(m_ui->shadowBuildDirEdit->path()); @@ -186,6 +182,18 @@ void Qt4BuildConfigWidget::shadowBuildLineEditTextChanged() m_ui->importLabel->setVisible(true); } } +} + +void Qt4BuildConfigWidget::shadowBuildLineEditTextChanged() +{ + if (m_pro->value(m_buildConfiguration, "buildDirectory").toString() == m_ui->shadowBuildDirEdit->path()) + m_pro->setValue(m_buildConfiguration, "buildDirectory", m_ui->shadowBuildDirEdit->path()); + // if the directory already exists + // check if we have a build in there and + // offer to import it + updateImportLabel(); + + m_pro->invalidateCachedTargetInformation(); // QFileInfo fi(m_ui->shadowBuildDirEdit->path()); // if (fi.exists()) { diff --git a/src/plugins/qt4projectmanager/qt4buildconfigwidget.h b/src/plugins/qt4projectmanager/qt4buildconfigwidget.h index edd74aa9f9e..0dffeed5104 100644 --- a/src/plugins/qt4projectmanager/qt4buildconfigwidget.h +++ b/src/plugins/qt4projectmanager/qt4buildconfigwidget.h @@ -63,6 +63,7 @@ private slots: void manageQtVersions(); private: + void updateImportLabel(); Ui::Qt4BuildConfigWidget *m_ui; Qt4Project *m_pro; QString m_buildConfiguration; diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp index a95c1284161..cf496f991bb 100644 --- a/src/plugins/qt4projectmanager/qt4project.cpp +++ b/src/plugins/qt4projectmanager/qt4project.cpp @@ -952,7 +952,7 @@ void Qt4Project::proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *nod foreach (QSharedPointer<RunConfiguration> rc, runConfigurations()) { if (QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>()) { if (qt4rc->proFilePath() == node->path()) { - qt4rc->updateCachedValues(); + qt4rc->invalidateCachedTargetInformation(); } } } @@ -1011,3 +1011,43 @@ void Qt4Project::notifyChanged(const QString &name) node->update(); } } + +void Qt4Project::invalidateCachedTargetInformation() +{ + foreach(QSharedPointer<RunConfiguration> rc, runConfigurations()) { + QSharedPointer<Qt4RunConfiguration> qt4rc = rc.dynamicCast<Qt4RunConfiguration>(); + if (qt4rc) { + qt4rc->invalidateCachedTargetInformation(); + } + } +} + + +/*! + Handle special case were a subproject of the qt directory is opened, and + qt was configured to be built as a shadow build -> also build in the sub- + project in the correct shadow build directory. + */ + +// TODO this function should be called on project first load +// and it should check against all configured qt versions ? +//void Qt4Project::detectQtShadowBuild(const QString &buildConfiguration) const +//{ +// if (project()->activeBuildConfiguration() == buildConfiguration) +// return; +// +// const QString currentQtDir = static_cast<Qt4Project *>(project())->qtDir(buildConfiguration); +// const QString qtSourceDir = static_cast<Qt4Project *>(project())->qtVersion(buildConfiguration)->sourcePath(); +// +// // if the project is a sub-project of Qt and Qt was shadow-built then automatically +// // adjust the build directory of the sub-project. +// if (project()->file()->fileName().startsWith(qtSourceDir) && qtSourceDir != currentQtDir) { +// project()->setValue(buildConfiguration, "useShadowBuild", true); +// QString buildDir = QFileInfo(project()->file()->fileName()).absolutePath(); +// buildDir.replace(qtSourceDir, currentQtDir); +// project()->setValue(buildConfiguration, "buildDirectory", buildDir); +// project()->setValue(buildConfiguration, "autoShadowBuild", true); +// } +//} + + diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h index 2b032c73c75..df23a18ba36 100644 --- a/src/plugins/qt4projectmanager/qt4project.h +++ b/src/plugins/qt4projectmanager/qt4project.h @@ -183,6 +183,11 @@ public: QString makeCommand(const QString &buildConfiguration) const; + // Is called by qmakestep qt4configurationwidget if the settings change + // Informs all Qt4RunConfigurations that their cached values are now invalid + // the Qt4RunConfigurations will update as soon as asked + void invalidateCachedTargetInformation(); + public slots: void update(); void proFileParseError(const QString &errorMessage); diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp index 433630e54c1..33d12957feb 100644 --- a/src/plugins/qt4projectmanager/qt4runconfiguration.cpp +++ b/src/plugins/qt4projectmanager/qt4runconfiguration.cpp @@ -58,17 +58,16 @@ Qt4RunConfiguration::Qt4RunConfiguration(Qt4Project *pro, QString proFilePath) m_userSetName(false), m_configWidget(0), m_executableLabel(0), - m_workingDirectoryLabel(0) + m_workingDirectoryLabel(0), + m_cachedTargetInformationValid(false) { setName(tr("Qt4RunConfiguration")); if (!m_proFilePath.isEmpty()) { - updateCachedValues(); setName(QFileInfo(m_proFilePath).baseName()); } + connect(pro, SIGNAL(activeBuildConfigurationChanged()), - this, SIGNAL(effectiveExecutableChanged())); - connect(pro, SIGNAL(activeBuildConfigurationChanged()), - this, SIGNAL(effectiveWorkingDirectoryChanged())); + this, SLOT(invalidateCachedTargetInformation())); } Qt4RunConfiguration::~Qt4RunConfiguration() @@ -87,7 +86,7 @@ QString Qt4RunConfiguration::type() const ///// Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4RunConfiguration, QWidget *parent) - : QWidget(parent), m_qt4RunConfiguration(qt4RunConfiguration), m_ignoreChange(false) + : QWidget(parent), m_qt4RunConfiguration(qt4RunConfiguration), m_ignoreChange(false), m_isShown(false) { QFormLayout *toplayout = new QFormLayout(this); toplayout->setMargin(0); @@ -128,11 +127,8 @@ Qt4RunConfigurationWidget::Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4Run connect(qt4RunConfiguration, SIGNAL(runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode)), this, SLOT(runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode))); - connect(qt4RunConfiguration, SIGNAL(effectiveExecutableChanged()), - this, SLOT(effectiveExecutableChanged())); - connect(qt4RunConfiguration, SIGNAL(effectiveWorkingDirectoryChanged()), - this, SLOT(effectiveWorkingDirectoryChanged())); - + connect(qt4RunConfiguration, SIGNAL(effectiveTargetInformationChanged()), + this, SLOT(effectiveTargetInformationChanged()), Qt::QueuedConnection); } void Qt4RunConfigurationWidget::setCommandLineArguments(const QString &args) @@ -175,18 +171,28 @@ void Qt4RunConfigurationWidget::runModeChanged(ApplicationRunConfiguration::RunM m_useTerminalCheck->setChecked(runMode == ApplicationRunConfiguration::Console); } -void Qt4RunConfigurationWidget::effectiveExecutableChanged() +void Qt4RunConfigurationWidget::effectiveTargetInformationChanged() { - m_executableLabel->setText(m_qt4RunConfiguration->executable()); + if (m_isShown) { + m_executableLabel->setText(m_qt4RunConfiguration->executable()); + m_workingDirectoryLabel->setText(m_qt4RunConfiguration->workingDirectory()); + } } -void Qt4RunConfigurationWidget::effectiveWorkingDirectoryChanged() +void Qt4RunConfigurationWidget::showEvent(QShowEvent *event) { - m_workingDirectoryLabel->setText(m_qt4RunConfiguration->workingDirectory()); + m_isShown = true; + effectiveTargetInformationChanged(); + QWidget::showEvent(event); } -////// TODO c&p above +void Qt4RunConfigurationWidget::hideEvent(QHideEvent *event) +{ + m_isShown = false; + QWidget::hideEvent(event); +} +////// TODO c&p above QWidget *Qt4RunConfiguration::configurationWidget() { return new Qt4RunConfigurationWidget(this, 0); @@ -209,7 +215,7 @@ void Qt4RunConfiguration::restore(const PersistentSettingsReader &reader) m_userSetName = reader.restoreValue("UserSetName").toBool(); m_runMode = reader.restoreValue("UseTerminal").toBool() ? Console : Gui; if (!m_proFilePath.isEmpty()) { - updateCachedValues(); + m_cachedTargetInformationValid = false; if (!m_userSetName) setName(QFileInfo(m_proFilePath).baseName()); } @@ -217,7 +223,8 @@ void Qt4RunConfiguration::restore(const PersistentSettingsReader &reader) QString Qt4RunConfiguration::executable() const { - return resolveVariables(project()->activeBuildConfiguration(), m_executable); + const_cast<Qt4RunConfiguration *>(this)->updateTarget(); + return m_executable; } ApplicationRunConfiguration::RunMode Qt4RunConfiguration::runMode() const @@ -227,7 +234,8 @@ ApplicationRunConfiguration::RunMode Qt4RunConfiguration::runMode() const QString Qt4RunConfiguration::workingDirectory() const { - return resolveVariables(project()->activeBuildConfiguration(), m_workingDir); + const_cast<Qt4RunConfiguration *>(this)->updateTarget(); + return m_workingDir; } QStringList Qt4RunConfiguration::commandLineArguments() const @@ -271,180 +279,99 @@ QString Qt4RunConfiguration::proFilePath() const return m_proFilePath; } -// and needs to be reloaded. -// Check wheter it is -void Qt4RunConfiguration::updateCachedValues() +void Qt4RunConfiguration::updateTarget() { - ProFileReader *reader = static_cast<Qt4Project *>(project())->createProFileReader(); + if (m_cachedTargetInformationValid) + return; + //qDebug()<<"updateTarget"; + Qt4Project *pro = static_cast<Qt4Project *>(project()); + ProFileReader *reader = pro->createProFileReader(); reader->setCumulative(false); + reader->setQtVersion(pro->qtVersion(pro->activeBuildConfiguration())); + + // Find out what flags we pass on to qmake, this code is duplicated in the qmake step + QtVersion::QmakeBuildConfig defaultBuildConfiguration = pro->qtVersion(pro->activeBuildConfiguration())->defaultBuildConfig(); + QtVersion::QmakeBuildConfig projectBuildConfiguration = QtVersion::QmakeBuildConfig(pro->qmakeStep()->value(pro->activeBuildConfiguration(), "buildConfiguration").toInt()); + QStringList addedUserConfigArguments; + QStringList removedUserConfigArguments; + if ((defaultBuildConfiguration & QtVersion::BuildAll) && !(projectBuildConfiguration & QtVersion::BuildAll)) + removedUserConfigArguments << "debug_and_release"; + if (!(defaultBuildConfiguration & QtVersion::BuildAll) && (projectBuildConfiguration & QtVersion::BuildAll)) + addedUserConfigArguments << "debug_and_release"; + if ((defaultBuildConfiguration & QtVersion::DebugBuild) && !(projectBuildConfiguration & QtVersion::DebugBuild)) + addedUserConfigArguments << "release"; + if (!(defaultBuildConfiguration & QtVersion::DebugBuild) && (projectBuildConfiguration & QtVersion::DebugBuild)) + addedUserConfigArguments << "debug"; + + reader->setUserConfigCmdArgs(addedUserConfigArguments, removedUserConfigArguments); + + QHash<QString, QStringList>::const_iterator it; + if (!reader->readProFile(m_proFilePath)) { delete reader; Core::ICore::instance()->messageManager()->printToOutputPane(QString("Could not parse %1. The Qt4 run configuration %2 can not be started.").arg(m_proFilePath).arg(name())); return; } - QString destDir; + // Extract data + QString relSubDir = QFileInfo(project()->file()->fileName()).absoluteDir().relativeFilePath(QFileInfo(m_proFilePath).path()); + QString baseDir = QDir(project()->buildDirectory(project()->activeBuildConfiguration())).absoluteFilePath(relSubDir); + + //qDebug()<<relSubDir<<baseDir; + // Working Directory if (reader->contains("DESTDIR")) { - // TODO Can return different destdirs for different scopes! - destDir = reader->value("DESTDIR"); - if (QDir::isRelativePath(destDir)) { - destDir = "${BASEDIR}" + QLatin1Char('/') + destDir; + //qDebug()<<"reader contains destdir:"<<reader->value("DESTDIR"); + m_workingDir = reader->value("DESTDIR"); + if (QDir::isRelativePath(m_workingDir)) { + m_workingDir = baseDir + QLatin1Char('/') + m_workingDir; + //qDebug()<<"was relative and expanded to"<<m_workingDir; } } else { - destDir = "${BASEDIR}"; + //qDebug()<<"reader didn't contain DESTDIR, setting to "<<baseDir; + m_workingDir = baseDir; + #if defined(Q_OS_WIN) + QString qmakeBuildConfig = "release"; + if (projectBuildConfiguration & QtVersion::DebugBuild) + qmakeBuildConfig = "debug"; if (!reader->contains("DESTDIR")) - destDir += QLatin1Char('/') + "${QMAKE_BUILDCONFIG}"; + destDir += QLatin1Char('/') + qmakeBuildConfig; #endif } #if defined (Q_OS_MAC) if (reader->values("CONFIG").contains("app_bundle")) { + QString qmakeBuildConfig = "release"; + if (projectBuildConfiguration & QtVersion::DebugBuild) + qmakeBuildConfig = "debug"; destDir += QLatin1Char('/') - + "${QMAKE_TARGET}" + + qmakeBuildConfig + QLatin1String(".app/Contents/MacOS"); } #endif - m_workingDir = destDir; - m_executable = destDir + QLatin1Char('/') + "${QMAKE_TARGET}"; + + m_workingDir = QDir::cleanPath(m_workingDir); + m_executable = QDir::cleanPath(m_workingDir + QLatin1Char('/') + reader->value("TARGET")); + //qDebug()<<"##### updateTarget sets:"<<m_workingDir<<m_executable; #if defined (Q_OS_WIN) m_executable += QLatin1String(".exe"); #endif - m_targets = reader->values(QLatin1String("TARGET")); - - m_srcDir = QFileInfo(m_proFilePath).path(); - delete reader; - emit effectiveExecutableChanged(); - emit effectiveWorkingDirectoryChanged(); -} - -QString Qt4RunConfiguration::resolveVariables(const QString &buildConfiguration, const QString& in) const -{ - detectQtShadowBuild(buildConfiguration); - - QString relSubDir = QFileInfo(project()->file()->fileName()).absoluteDir().relativeFilePath(m_srcDir); - QString baseDir = QDir(project()->buildDirectory(buildConfiguration)).absoluteFilePath(relSubDir); - - Core::VariableManager *vm = Core::ICore::instance()->variableManager(); - if (!vm) - return QString(); - QString dest; - bool found = false; - vm->insert("QMAKE_BUILDCONFIG", qmakeBuildConfigFromBuildConfiguration(buildConfiguration)); - vm->insert("BASEDIR", baseDir); - - - /* - TODO This is a hack to detect correct target (there might be different targets in - different scopes) - */ - - // This code also works for workingDirectory, - // since directories are executable. - foreach (const QString &target, m_targets) { - dest = in; - vm->insert("QMAKE_TARGET", target); - dest = QDir::cleanPath(vm->resolve(dest)); - vm->remove("QMAKE_TARGET"); - QFileInfo fi(dest); - if (fi.exists() && (fi.isExecutable() || dest.endsWith(".js"))) { - found = true; - break; - } - } - vm->remove("BASEDIR"); - vm->remove("QMAKE_BUILDCONFIG"); - if (found) - return dest; - else - return QString(); -} - -/* This function tries to find out wheter qmake/make will put the binary in "/debug/" or in "/release/" - That is this function is strictly only for windows. - We look wheter make gets an explicit parameter "debug" or "release" - That works because if we have either debug or release there then it is surely a - debug_and_release buildconfiguration and thus we are put in a subdirectory. - - Now if there is no explicit debug or release parameter, then we need to look at what qmake's CONFIG - value is, if it is not debug_and_release, we don't care and return "" - otherwise we look at wheter the default is debug or not - - Note: When fixing this function consider those cases - qmake CONFIG+=debug_and_release CONFIG+=debug - make release - => we should return release - - qmake CONFIG+=debug_and_release CONFIG+=debug - make - => we should return debug - - qmake CONFIG-=debug_and_release CONFIG+=debug - make - => we should return "", since the executable is not put in a subdirectory - - Not a function to be proud of -*/ -QString Qt4RunConfiguration::qmakeBuildConfigFromBuildConfiguration(const QString &buildConfigurationName) const -{ - MakeStep *ms = qobject_cast<Qt4Project *>(project())->makeStep(); - QStringList makeargs = ms->value(buildConfigurationName, "makeargs").toStringList(); - if (makeargs.contains("debug")) - return "debug"; - else if (makeargs.contains("release")) - return "release"; - - // Oh we don't have an explicit make argument - QMakeStep *qs = qobject_cast<Qt4Project *>(project())->qmakeStep(); - QVariant qmakeBuildConfiguration = qs->value(buildConfigurationName, "buildConfiguration"); - if (qmakeBuildConfiguration.isValid()) { - QtVersion::QmakeBuildConfig projectBuildConfiguration = QtVersion::QmakeBuildConfig(qmakeBuildConfiguration.toInt()); - if (projectBuildConfiguration & QtVersion::DebugBuild) - return "debug"; - else - return "release"; - } else { - // Old style always CONFIG+=debug_and_release - if (qobject_cast<Qt4Project *>(project())->qtVersion(buildConfigurationName)->defaultBuildConfig() & QtVersion::DebugBuild) - return "debug"; - else - return "release"; - } + m_cachedTargetInformationValid = true; - // enable us to infer the right string - return ""; + emit effectiveTargetInformationChanged(); } -/*! - Handle special case were a subproject of the qt directory is opened, and - qt was configured to be built as a shadow build -> also build in the sub- - project in the correct shadow build directory. - */ -void Qt4RunConfiguration::detectQtShadowBuild(const QString &buildConfiguration) const +void Qt4RunConfiguration::invalidateCachedTargetInformation() { - if (project()->activeBuildConfiguration() == buildConfiguration) - return; - - const QString currentQtDir = static_cast<Qt4Project *>(project())->qtDir(buildConfiguration); - const QString qtSourceDir = static_cast<Qt4Project *>(project())->qtVersion(buildConfiguration)->sourcePath(); - - // if the project is a sub-project of Qt and Qt was shadow-built then automatically - // adjust the build directory of the sub-project. - if (project()->file()->fileName().startsWith(qtSourceDir) && qtSourceDir != currentQtDir) { - project()->setValue(buildConfiguration, "useShadowBuild", true); - QString buildDir = QFileInfo(project()->file()->fileName()).absolutePath(); - buildDir.replace(qtSourceDir, currentQtDir); - project()->setValue(buildConfiguration, "buildDirectory", buildDir); - project()->setValue(buildConfiguration, "autoShadowBuild", true); - } + m_cachedTargetInformationValid = false; + emit effectiveTargetInformationChanged(); } - /// /// Qt4RunConfigurationFactory /// This class is used to restore run settings (saved in .user files) diff --git a/src/plugins/qt4projectmanager/qt4runconfiguration.h b/src/plugins/qt4projectmanager/qt4runconfiguration.h index d848531d013..7828270a5c7 100644 --- a/src/plugins/qt4projectmanager/qt4runconfiguration.h +++ b/src/plugins/qt4projectmanager/qt4runconfiguration.h @@ -73,8 +73,15 @@ public: QString proFilePath() const; - // Should just be called from qt4project, since that knows that the file changed on disc - void updateCachedValues(); + // TODO detectQtShadowBuild() ? how did this work ? + +public slots: + // This function is called if: + // X the pro file changes + // X the active buildconfiguration changes + // X the qmake parameters change + // X the build directory changes + void invalidateCachedTargetInformation(); signals: void nameChanged(const QString&); @@ -82,8 +89,7 @@ signals: void runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode runMode); // note those signals might not emited for every change - void effectiveExecutableChanged(); - void effectiveWorkingDirectoryChanged(); + void effectiveTargetInformationChanged(); private slots: void setCommandLineArguments(const QString &argumentsString); @@ -91,10 +97,7 @@ private slots: void setRunMode(RunMode runMode); private: - void detectQtShadowBuild(const QString &buildConfig) const; - QString resolveVariables(const QString &buildConfiguration, const QString& in) const; - QString qmakeBuildConfigFromBuildConfiguration(const QString &buildConfigurationName) const; - + void updateTarget(); QStringList m_commandLineArguments; Qt4ProFileNode *m_proFileNode; QString m_proFilePath; // Full path to the Application Pro File @@ -102,13 +105,13 @@ private: // Cached startup sub project information QStringList m_targets; QString m_executable; - QString m_srcDir; QString m_workingDir; ProjectExplorer::ApplicationRunConfiguration::RunMode m_runMode; bool m_userSetName; QWidget *m_configWidget; QLabel *m_executableLabel; QLabel *m_workingDirectoryLabel; + bool m_cachedTargetInformationValid; }; class Qt4RunConfigurationWidget : public QWidget @@ -116,6 +119,9 @@ class Qt4RunConfigurationWidget : public QWidget Q_OBJECT public: Qt4RunConfigurationWidget(Qt4RunConfiguration *qt4runconfigration, QWidget *parent); +protected: + void showEvent(QShowEvent *event); + void hideEvent(QHideEvent *event); private slots: void setCommandLineArguments(const QString &arguments); void nameEdited(const QString &name); @@ -123,8 +129,7 @@ private slots: void commandLineArgumentsChanged(const QString &args); void nameChanged(const QString &name); void runModeChanged(ProjectExplorer::ApplicationRunConfiguration::RunMode runMode); - void effectiveExecutableChanged(); - void effectiveWorkingDirectoryChanged(); + void effectiveTargetInformationChanged(); void termToggled(bool); private: Qt4RunConfiguration *m_qt4RunConfiguration; @@ -134,6 +139,7 @@ private: QLineEdit *m_nameLineEdit; QLineEdit *m_argumentsLineEdit; QCheckBox *m_useTerminalCheck; + bool m_isShown; }; class Qt4RunConfigurationFactory : public ProjectExplorer::IRunConfigurationFactory diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 64a75c0256a..bbfeba7dd7e 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -217,6 +217,8 @@ public: int m_prevLineNo; // Checking whether we're assigning the same TARGET ProFile *m_prevProFile; // See m_prevLineNo + QStringList m_addUserConfigCmdArgs; + QStringList m_removeUserConfigCmdArgs; }; ProFileEvaluator::Private::Private(ProFileEvaluator *q_) @@ -628,6 +630,12 @@ bool ProFileEvaluator::Private::visitBeginProFile(ProFile * pro) // But this also creates a lot of problems evaluateFile(mkspecDirectory + QLatin1String("/default/qmake.conf"), &ok); evaluateFile(mkspecDirectory + QLatin1String("/features/default_pre.prf"), &ok); + + QStringList tmp = m_valuemap.value("CONFIG"); + tmp.append(m_addUserConfigCmdArgs); + foreach(const QString &remove, m_removeUserConfigCmdArgs) + tmp.removeAll(remove); + m_valuemap.insert("CONFIG", tmp); m_cumulative = cumulative; } @@ -822,6 +830,7 @@ bool ProFileEvaluator::Private::visitProValue(ProValue *value) // but this will break just as much as it fixes, so leave it as is. replaceInList(&m_tempValuemap[varName], regexp, replace, global); replaceInList(&m_tempFilevaluemap[currentProFile()][varName], regexp, replace, global); + } } break; @@ -1679,14 +1688,16 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct } const QStringList mutuals = args[1].split(QLatin1Char('|')); const QStringList &configs = valuesDirect(QLatin1String("CONFIG")); + for (int i = configs.size() - 1; i >= 0; i--) { for (int mut = 0; mut < mutuals.count(); mut++) { if (configs[i] == mutuals[mut].trimmed()) { cond = (configs[i] == args[0]); - break; + goto done_T_CONFIG; } } } + done_T_CONFIG: break; } case T_CONTAINS: { @@ -1713,12 +1724,12 @@ bool ProFileEvaluator::Private::evaluateConditionalFunction(const QString &funct for (int mut = 0; mut < mutuals.count(); mut++) { if (val == mutuals[mut].trimmed()) { cond = (regx.exactMatch(val) || val == args[1]); - break; + goto done_T_CONTAINS; } } } } - + done_T_CONTAINS: break; } case T_COUNT: { @@ -2284,6 +2295,12 @@ void ProFileEvaluator::setOutputDir(const QString &dir) d->m_outputDir = dir; } +void ProFileEvaluator::setUserConfigCmdArgs(const QStringList &addUserConfigCmdArgs, const QStringList &removeUserConfigCmdArgs) +{ + d->m_addUserConfigCmdArgs = addUserConfigCmdArgs; + d->m_removeUserConfigCmdArgs = removeUserConfigCmdArgs; +} + void evaluateProFile(const ProFileEvaluator &visitor, QHash<QByteArray, QStringList> *varMap) { QStringList sourceFiles; diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index 452b2ceceb3..b6df287b7d7 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -65,6 +65,7 @@ public: void setVerbose(bool on); // Default is false void setCumulative(bool on); // Default is true! void setOutputDir(const QString &dir); // Default is empty + void setUserConfigCmdArgs(const QStringList &addUserConfigCmdArgs, const QStringList &removeUserConfigCmdArgs); bool queryProFile(ProFile *pro); bool accept(ProFile *pro); -- GitLab