From 08d905ae3d9715b7628e3f8f522f85df3d1eed48 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 6 Jun 2019 13:38:28 +0200 Subject: [PATCH] CMake: Store pointer to CMakeProject in BuildDirManager Use this back-pointer to validate the buildconfiguration. Use the validated buildconfiguration consistently. In theory the buildconfiguration is valid at all times (since deleting a buildconfiguration will trigger an update to the parameters in BuildDirManager), but better be safe. Change-Id: I614d9ce16e4974a9437a2f44756f01c71a5ede13 Reviewed-by: hjk --- .../cmakeprojectmanager/builddirmanager.cpp | 30 +++++++++++-------- .../cmakeprojectmanager/builddirmanager.h | 7 ++++- .../cmakeprojectmanager/cmakeproject.cpp | 20 ++++++------- 3 files changed, 34 insertions(+), 23 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index fc443f4c767..dee7f110230 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -59,7 +59,8 @@ namespace Internal { // BuildDirManager: // -------------------------------------------------------------------- -BuildDirManager::BuildDirManager() = default; +BuildDirManager::BuildDirManager(CMakeProject *project) : m_project(project) { assert(project); } + BuildDirManager::~BuildDirManager() = default; Utils::FilePath BuildDirManager::workDirectory(const BuildDirParameters ¶meters) const @@ -227,15 +228,19 @@ void BuildDirManager::setParametersAndRequestParse(const BuildDirParameters &par CMakeBuildConfiguration *BuildDirManager::buildConfiguration() const { - return m_parameters.buildConfiguration; + if (m_project->activeTarget() && m_project->activeTarget()->activeBuildConfiguration() == m_parameters.buildConfiguration) + return m_parameters.buildConfiguration; + return nullptr; +} + +FilePath BuildDirManager::buildDirectory() const +{ + return buildConfiguration() ? m_parameters.buildDirectory : FilePath(); } void BuildDirManager::becameDirty() { - if (isParsing()) - return; - - if (!m_parameters.buildConfiguration || !m_parameters.buildConfiguration->isActive()) + if (isParsing() || !buildConfiguration()) return; const CMakeTool *tool = m_parameters.cmakeTool(); @@ -327,8 +332,8 @@ static CMakeBuildTarget utilityTarget(const QString &title, const BuildDirManage target.title = title; target.targetType = UtilityType; - target.workingDirectory = bdm->buildConfiguration()->buildDirectory(); - target.sourceDirectory = bdm->buildConfiguration()->target()->project()->projectDirectory(); + target.workingDirectory = bdm->buildDirectory(); + target.sourceDirectory = bdm->project()->projectDirectory(); return target; } @@ -380,12 +385,13 @@ CMakeConfig BuildDirManager::parseCMakeConfiguration(const Utils::FilePath &cach bool BuildDirManager::checkConfiguration() { - QTC_ASSERT(m_parameters.isValid(), return false); + CMakeBuildConfiguration *bc = buildConfiguration(); + QTC_ASSERT(m_parameters.isValid() || !bc, return false); if (m_parameters.workDirectory != m_parameters.buildDirectory) // always throw away changes in the tmpdir! return false; - const CMakeConfig cache = m_parameters.buildConfiguration->configurationFromCMake(); + const CMakeConfig cache = bc->configurationFromCMake(); if (cache.isEmpty()) return false; // No cache file yet. @@ -431,8 +437,8 @@ bool BuildDirManager::checkConfiguration() box->exec(); if (box->clickedButton() == applyButton) { m_parameters.configuration = newConfig; - QSignalBlocker blocker(m_parameters.buildConfiguration); - m_parameters.buildConfiguration->setConfigurationForCMake(newConfig); + QSignalBlocker blocker(bc); + bc->setConfigurationForCMake(newConfig); return false; } else if (box->clickedButton() == defaultButton) return true; diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index e2f9b8ff058..ff93e48743f 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -46,6 +46,7 @@ namespace ProjectExplorer { class FileNode; } namespace CMakeProjectManager { +class CMakeProject; class CMakeTool; namespace Internal { @@ -58,14 +59,17 @@ class BuildDirManager : public QObject Q_OBJECT public: - BuildDirManager(); + BuildDirManager(CMakeProject *project); ~BuildDirManager() final; bool isParsing() const; void setParametersAndRequestParse(const BuildDirParameters ¶meters, int newReaderReparseOptions, int existingReaderReparseOptions); + // nullptr if the BC is not active anymore! CMakeBuildConfiguration *buildConfiguration() const; + CMakeProject *project() const {return m_project; } + Utils::FilePath buildDirectory() const; void clearCache(); @@ -114,6 +118,7 @@ private: void becameDirty(); BuildDirParameters m_parameters; + CMakeProject *m_project = nullptr; mutable std::unordered_map> m_buildDirToTempDir; mutable std::unique_ptr m_reader; mutable bool m_isHandlingError = false; diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index d064120f295..e823ed43a00 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -82,7 +82,8 @@ static CMakeBuildConfiguration *activeBc(const CMakeProject *p) \class CMakeProject */ CMakeProject::CMakeProject(const FilePath &fileName) : Project(Constants::CMAKEMIMETYPE, fileName), - m_cppCodeModelUpdater(new CppTools::CppProjectUpdater) + m_cppCodeModelUpdater(new CppTools::CppProjectUpdater), + m_buildDirManager(this) { setId(CMakeProjectManager::Constants::CMAKEPROJECT_ID); setProjectLanguages(Core::Context(ProjectExplorer::Constants::CXX_LANGUAGE_ID)); @@ -100,16 +101,16 @@ CMakeProject::CMakeProject(const FilePath &fileName) : Project(Constants::CMAKEM this, &CMakeProject::handleReparseRequest); connect(&m_buildDirManager, &BuildDirManager::dataAvailable, this, [this]() { - CMakeBuildConfiguration *bc = activeBc(this); - if (bc && bc == m_buildDirManager.buildConfiguration()) { + CMakeBuildConfiguration *bc = m_buildDirManager.buildConfiguration(); + if (bc) { bc->clearError(); handleParsingSuccess(bc); } }); connect(&m_buildDirManager, &BuildDirManager::errorOccured, this, [this](const QString &msg) { - CMakeBuildConfiguration *bc = activeBc(this); - if (bc && bc == m_buildDirManager.buildConfiguration()) { + CMakeBuildConfiguration *bc = m_buildDirManager.buildConfiguration(); + if (bc) { bc->setError(msg); bc->setConfigurationFromCMake(m_buildDirManager.takeCMakeConfiguration()); handleParsingError(bc); @@ -117,8 +118,8 @@ CMakeProject::CMakeProject(const FilePath &fileName) : Project(Constants::CMAKEM }); connect(&m_buildDirManager, &BuildDirManager::parsingStarted, this, [this]() { - CMakeBuildConfiguration *bc = activeBc(this); - if (bc && bc == m_buildDirManager.buildConfiguration()) + CMakeBuildConfiguration *bc = m_buildDirManager.buildConfiguration(); + if (bc) bc->clearError(CMakeBuildConfiguration::ForceEnabledChanged::True); }); @@ -186,7 +187,7 @@ CMakeProject::CMakeProject(const FilePath &fileName) : Project(Constants::CMAKEM subscribeSignal(&CMakeBuildConfiguration::buildDirectoryChanged, this, [this]() { auto senderBc = qobject_cast(sender()); - if (senderBc && senderBc->isActive() && senderBc == m_buildDirManager.buildConfiguration()) { + if (senderBc && senderBc == m_buildDirManager.buildConfiguration()) { // The build directory of our BC has changed: // * Error out if the reader updates, cannot happen since all BCs share a target/kit. // * run cmake without configuration arguments if the reader stays @@ -201,7 +202,7 @@ CMakeProject::CMakeProject(const FilePath &fileName) : Project(Constants::CMAKEM subscribeSignal(&CMakeBuildConfiguration::configurationForCMakeChanged, this, [this]() { auto senderBc = qobject_cast(sender()); - if (senderBc && senderBc->isActive() && senderBc == m_buildDirManager.buildConfiguration()) { + if (senderBc && senderBc == m_buildDirManager.buildConfiguration()) { // The CMake configuration has changed on our BC: // * Error out if the reader updates, cannot happen since all BCs share a target/kit. // * run cmake with configuration arguments if the reader stays @@ -565,7 +566,6 @@ void CMakeProject::handleParsingError(CMakeBuildConfiguration *bc) combineScanAndParse(bc); } - void CMakeProject::combineScanAndParse(CMakeBuildConfiguration *bc) { QTC_ASSERT(bc && bc->isActive(), return);