From 637d45c66a1e1eb30db2479a132cbb72bee097a7 Mon Sep 17 00:00:00 2001 From: Cristian Adam Date: Thu, 18 Mar 2021 14:20:02 +0100 Subject: [PATCH] CMakePM: Make "Build type" aspect visible For single configuration projects if you change the build type aspect you will change the CMAKE_BUILD_TYPE variable. When switching the build directory the existing CMAKE_BUILD_TYPE will be set as build type aspect. Fixes: QTCREATORBUG-25451 Change-Id: I13519e95c316c556cc1348fba6121637d2fd4275 Reviewed-by: Eike Ziller --- src/libs/utils/aspects.cpp | 2 +- src/libs/utils/aspects.h | 2 +- .../builddirparameters.cpp | 10 --- .../cmakebuildconfiguration.cpp | 64 ++++++++++++++++++- .../cmakebuildconfiguration.h | 5 +- .../cmakeprojectmanager/cmakebuildsystem.cpp | 12 +++- 6 files changed, 77 insertions(+), 18 deletions(-) diff --git a/src/libs/utils/aspects.cpp b/src/libs/utils/aspects.cpp index e5f0aba77c1..ef0f7b1866b 100644 --- a/src/libs/utils/aspects.cpp +++ b/src/libs/utils/aspects.cpp @@ -640,7 +640,7 @@ void StringAspect::setValue(const QString &val) void StringAspect::fromMap(const QVariantMap &map) { if (!settingsKey().isEmpty()) - BaseAspect::setValueQuietly(map.value(settingsKey())); + BaseAspect::setValueQuietly(map.value(settingsKey(), defaultValue())); if (d->m_checker) d->m_checker->fromMap(map); } diff --git a/src/libs/utils/aspects.h b/src/libs/utils/aspects.h index 7a21b29e4bd..0b076340e02 100644 --- a/src/libs/utils/aspects.h +++ b/src/libs/utils/aspects.h @@ -303,7 +303,7 @@ public: signals: void checkedChanged(); -private: +protected: void update(); std::unique_ptr d; diff --git a/src/plugins/cmakeprojectmanager/builddirparameters.cpp b/src/plugins/cmakeprojectmanager/builddirparameters.cpp index 0c06c329f58..005a87cabfc 100644 --- a/src/plugins/cmakeprojectmanager/builddirparameters.cpp +++ b/src/plugins/cmakeprojectmanager/builddirparameters.cpp @@ -76,16 +76,6 @@ BuildDirParameters::BuildDirParameters(CMakeBuildConfiguration *bc) buildDirectory = bc->buildDirectory(); cmakeBuildType = bc->cmakeBuildType(); - if (cmakeBuildType.isEmpty()) { - // The empty build type might be just a case of loading of an existing project - // that doesn't have the "CMake.Build.Type" aspect saved - const CMakeConfig config = CMakeConfigItem::itemsFromArguments(initialCMakeArguments); - if (!config.isEmpty()) { - cmakeBuildType = QString::fromLatin1(CMakeConfigItem::valueOf("CMAKE_BUILD_TYPE", config)); - if (!cmakeBuildType.isEmpty()) - bc->setCMakeBuildType(cmakeBuildType); - } - } environment = bc->environment(); // Disable distributed building for configuration runs. CMake does not do those in parallel, diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 62cda21e599..41abdd62431 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -189,6 +189,17 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc) buildDirAspect->addToLayout(aspectWidgetBuilder); aspectWidgetBuilder.finishRow(); initialCMakeAspect->addToLayout(aspectWidgetBuilder); + aspectWidgetBuilder.finishRow(); + auto buildTypeAspect = bc->aspect(); + connect(buildTypeAspect, &BaseAspect::changed, this, [this, buildTypeAspect]() { + if (!m_buildConfiguration->isMultiConfig()) { + CMakeConfig config; + config << CMakeConfigItem("CMAKE_BUILD_TYPE", buildTypeAspect->value().toUtf8()); + + m_configModel->setBatchEditConfiguration(config); + } + }); + buildTypeAspect->addToLayout(aspectWidgetBuilder); mainLayout->addWidget(aspectWidget, row, 0, 1, -1); ++row; @@ -1257,12 +1268,56 @@ FilePath CMakeBuildConfiguration::sourceDirectory() const QString CMakeBuildConfiguration::cmakeBuildType() const { - return aspect()->value(); + if (!isMultiConfig()) { + auto configChanges = configurationChanges(); + auto it = std::find_if(configChanges.begin(), configChanges.end(), + [](const CMakeConfigItem &item) { return item.key == "CMAKE_BUILD_TYPE";}); + if (it != configChanges.end()) + const_cast(this) + ->setCMakeBuildType(QString::fromUtf8(it->value)); + } + + QString cmakeBuildType = aspect()->value(); + + const Utils::FilePath cmakeCacheTxt = buildDirectory().pathAppended("CMakeCache.txt"); + const bool hasCMakeCache = QFile::exists(cmakeCacheTxt.toString()); + CMakeConfig config; + + if (cmakeBuildType == "Unknown") { + // The "Unknown" type is the case of loading of an existing project + // that doesn't have the "CMake.Build.Type" aspect saved + if (hasCMakeCache) { + QString errorMessage; + config = CMakeBuildSystem::parseCMakeCacheDotTxt(cmakeCacheTxt, &errorMessage); + } else { + config = CMakeConfigItem::itemsFromArguments(initialCMakeArguments()); + } + } else if (!hasCMakeCache) { + config = CMakeConfigItem::itemsFromArguments(initialCMakeArguments()); + } + + if (!config.isEmpty()) { + cmakeBuildType = QString::fromUtf8(CMakeConfigItem::valueOf("CMAKE_BUILD_TYPE", config)); + const_cast(this) + ->setCMakeBuildType(cmakeBuildType); + } + + return cmakeBuildType; } -void CMakeBuildConfiguration::setCMakeBuildType(const QString &cmakeBuildType) +void CMakeBuildConfiguration::setCMakeBuildType(const QString &cmakeBuildType, bool quiet) { - aspect()->setValue(cmakeBuildType); + if (quiet) { + aspect()->setValueQuietly(cmakeBuildType); + aspect()->update(); + } else { + aspect()->setValue(cmakeBuildType); + } +} + +bool CMakeBuildConfiguration::isMultiConfig() const +{ + return m_buildSystem->isMultiConfig(); } namespace Internal { @@ -1293,6 +1348,9 @@ SourceDirectoryAspect::SourceDirectoryAspect() BuildTypeAspect::BuildTypeAspect() { setSettingsKey("CMake.Build.Type"); + setLabelText(tr("Build type:")); + setDisplayStyle(LineEditDisplay); + setDefaultValue("Unknown"); } } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h index 24dbaaca436..32ced5031ef 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.h @@ -75,7 +75,9 @@ public: Utils::FilePath sourceDirectory() const; QString cmakeBuildType() const; - void setCMakeBuildType(const QString &cmakeBuildType); + void setCMakeBuildType(const QString &cmakeBuildType, bool quiet = false); + + bool isMultiConfig() const; signals: void errorOccurred(const QString &message); @@ -163,6 +165,7 @@ class BuildTypeAspect final : public Utils::StringAspect public: BuildTypeAspect(); + using Utils::StringAspect::update; }; } // namespace Internal diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index 67cc7daa0b7..38ded553b24 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -820,12 +820,20 @@ void CMakeBuildSystem::wireUpConnections() // No CMakeCache? Run with initial arguments! qCDebug(cmakeBuildSystemLog) << "Requesting parse due to build directory change"; const BuildDirParameters parameters(cmakeBuildConfiguration()); - const bool hasCMakeCache = QFile::exists( - (parameters.buildDirectory / "CMakeCache.txt").toString()); + const FilePath cmakeCacheTxt = parameters.buildDirectory.pathAppended("CMakeCache.txt"); + const bool hasCMakeCache = QFile::exists(cmakeCacheTxt.toString()); const auto options = ReparseParameters( hasCMakeCache ? REPARSE_DEFAULT : (REPARSE_FORCE_INITIAL_CONFIGURATION | REPARSE_FORCE_CMAKE_RUN)); + if (hasCMakeCache) { + QString errorMessage; + const CMakeConfig config = CMakeBuildSystem::parseCMakeCacheDotTxt(cmakeCacheTxt, &errorMessage); + if (!config.isEmpty() && errorMessage.isEmpty()) { + QByteArray cmakeBuildTypeName = CMakeConfigItem::valueOf("CMAKE_BUILD_TYPE", config); + cmakeBuildConfiguration()->setCMakeBuildType(QString::fromUtf8(cmakeBuildTypeName), true); + } + } setParametersAndRequestParse(BuildDirParameters(cmakeBuildConfiguration()), options); });