diff --git a/src/plugins/projectexplorer/buildconfiguration.cpp b/src/plugins/projectexplorer/buildconfiguration.cpp index 750b1363a47..70a4e60deb6 100644 --- a/src/plugins/projectexplorer/buildconfiguration.cpp +++ b/src/plugins/projectexplorer/buildconfiguration.cpp @@ -531,13 +531,11 @@ void BuildConfiguration::setUserEnvironmentChanges(const EnvironmentItems &diff) bool BuildConfiguration::isEnabled() const { - return !buildSystem()->isParsing() && buildSystem()->hasParsingData(); + return buildSystem()->hasParsingData(); } QString BuildConfiguration::disabledReason() const { - if (buildSystem()->isParsing()) - return (tr("The project is currently being parsed.")); if (!buildSystem()->hasParsingData()) return (tr("The project was not parsed successfully.")); return QString(); diff --git a/src/plugins/projectexplorer/buildconfiguration.h b/src/plugins/projectexplorer/buildconfiguration.h index 73d2eb3fe9a..40f7dd72ce0 100644 --- a/src/plugins/projectexplorer/buildconfiguration.h +++ b/src/plugins/projectexplorer/buildconfiguration.h @@ -91,8 +91,8 @@ public: bool fromMap(const QVariantMap &map) override; QVariantMap toMap() const override; - virtual bool isEnabled() const; - virtual QString disabledReason() const; + bool isEnabled() const; + QString disabledReason() const; virtual bool regenerateBuildFiles(Node *node); diff --git a/src/plugins/projectexplorer/buildmanager.cpp b/src/plugins/projectexplorer/buildmanager.cpp index 502ba4490a8..0c2c1cdd61e 100644 --- a/src/plugins/projectexplorer/buildmanager.cpp +++ b/src/plugins/projectexplorer/buildmanager.cpp @@ -27,6 +27,7 @@ #include "buildprogress.h" #include "buildsteplist.h" +#include "buildsystem.h" #include "compileoutputwindow.h" #include "deployconfiguration.h" #include "kit.h" @@ -46,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -57,6 +59,7 @@ #include #include #include +#include #include #include @@ -215,6 +218,7 @@ public: Internal::CompileOutputWindow *m_outputWindow = nullptr; Internal::TaskWindow *m_taskWindow = nullptr; + QMetaObject::Connection m_scheduledBuild; QList m_buildQueue; QList m_enabledState; QStringList m_stepNames; @@ -459,6 +463,12 @@ QString BuildManager::displayNameForStepId(Id stepId) void BuildManager::cancel() { + if (d->m_scheduledBuild) { + disconnect(d->m_scheduledBuild); + d->m_scheduledBuild = {}; + clearBuildQueue(); + return; + } if (d->m_running) { if (d->m_canceling) return; @@ -502,11 +512,13 @@ void BuildManager::clearBuildQueue() d->m_previousBuildStepProject = nullptr; d->m_currentBuildStep = nullptr; - d->m_progressFutureInterface->reportCanceled(); - d->m_progressFutureInterface->reportFinished(); - d->m_progressWatcher.setFuture(QFuture()); - delete d->m_progressFutureInterface; - d->m_progressFutureInterface = nullptr; + if (d->m_progressFutureInterface) { + d->m_progressFutureInterface->reportCanceled(); + d->m_progressFutureInterface->reportFinished(); + d->m_progressWatcher.setFuture(QFuture()); + delete d->m_progressFutureInterface; + d->m_progressFutureInterface = nullptr; + } d->m_futureProgress = nullptr; d->m_maxProgress = 0; @@ -544,6 +556,28 @@ void BuildManager::startBuildQueue() emit m_instance->buildQueueFinished(true); return; } + + // Delay if any of the involved build systems are currently parsing. + const auto buildSystems = transform>(d->m_buildQueue, + [](const BuildStep *bs) { return bs->buildSystem(); }); + for (const BuildSystem * const bs : buildSystems) { + if (!bs || !bs->isParsing()) + continue; + d->m_scheduledBuild = QObject::connect(bs, &BuildSystem::parsingFinished, + BuildManager::instance(), + [](bool parsingSuccess) { + if (!d->m_scheduledBuild) + return; + QObject::disconnect(d->m_scheduledBuild); + d->m_scheduledBuild = {}; + if (parsingSuccess) + startBuildQueue(); + else + clearBuildQueue(); + }, Qt::QueuedConnection); + return; + } + if (!d->m_running) { d->m_elapsed.start(); // Progress Reporting diff --git a/src/plugins/projectexplorer/buildsystem.cpp b/src/plugins/projectexplorer/buildsystem.cpp index 79e4e3ff2b0..d91558ea44e 100644 --- a/src/plugins/projectexplorer/buildsystem.cpp +++ b/src/plugins/projectexplorer/buildsystem.cpp @@ -107,7 +107,6 @@ void BuildSystem::emitParsingStarted() QTC_ASSERT(!d->m_isParsing, return); d->m_isParsing = true; - d->m_hasParsingData = false; emit parsingStarted(); emit d->m_target->parsingStarted(); } diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 118e39fb9e2..8babc8f6d8d 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -2870,6 +2870,11 @@ void ProjectExplorerPlugin::runRunConfiguration(RunConfiguration *rc, { if (!rc->isEnabled()) return; + const auto delay = [rc, runMode] { + dd->m_runMode = runMode; + dd->m_delayedRunConfiguration = rc; + dd->m_shouldHaveRunConfiguration = true; + }; const BuildForRunConfigStatus buildStatus = forceSkipDeploy ? BuildManager::isBuilding(rc->project()) ? BuildForRunConfigStatus::Building : BuildForRunConfigStatus::NotBuilding @@ -2879,14 +2884,13 @@ void ProjectExplorerPlugin::runRunConfiguration(RunConfiguration *rc, return; case BuildForRunConfigStatus::Building: QTC_ASSERT(dd->m_runMode == Constants::NO_RUN_MODE, return); - - // delay running till after our queued steps were processed - dd->m_runMode = runMode; - dd->m_delayedRunConfiguration = rc; - dd->m_shouldHaveRunConfiguration = true; + delay(); break; case BuildForRunConfigStatus::NotBuilding: - dd->executeRunConfiguration(rc, runMode); + if (rc->isEnabled()) + dd->executeRunConfiguration(rc, runMode); + else + delay(); break; } diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp index 00ccdf8459a..da9e6abd46c 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp @@ -199,7 +199,7 @@ QbsBuildStep::~QbsBuildStep() bool QbsBuildStep::init() { - if (qbsBuildSystem()->isParsing() || m_session) + if (m_session) return false; auto bc = static_cast(buildConfiguration()); diff --git a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp index f5d144875e1..999f34e426e 100644 --- a/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp +++ b/src/plugins/qmlprojectmanager/qmlprojectrunconfiguration.cpp @@ -231,11 +231,8 @@ QString QmlProjectRunConfiguration::commandLineArguments() const bool QmlProjectRunConfiguration::isEnabled() const { - if (m_qmlMainFileAspect->isQmlFilePresent() && !commandLine().executable().isEmpty()) { - BuildSystem *bs = activeBuildSystem(); - return !bs->isParsing() && bs->hasParsingData(); - } - return false; + return m_qmlMainFileAspect->isQmlFilePresent() && !commandLine().executable().isEmpty() + && activeBuildSystem()->hasParsingData(); } QString QmlProjectRunConfiguration::mainScript() const