diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp index 32a00daf5b0..6e7638e2d03 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp +++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.cpp @@ -39,6 +39,7 @@ #include #include +#include #include #include #include @@ -875,6 +876,7 @@ const char CMAKE_CXX_TOOLCHAIN_KEY[] = "CMAKE_CXX_COMPILER"; const char CMAKE_QMAKE_KEY[] = "QT_QMAKE_EXECUTABLE"; const char CMAKE_PREFIX_PATH_KEY[] = "CMAKE_PREFIX_PATH"; const char QTC_CMAKE_PRESET_KEY[] = "QTC_CMAKE_PRESET"; +const char QTC_KIT_DEFAULT_CONFIG_HASH[] = "QTC_KIT_DEFAULT_CONFIG_HASH"; class CMakeConfigurationKitAspectWidget final : public KitAspectWidget { @@ -1135,6 +1137,43 @@ CMakeConfigItem CMakeConfigurationKitAspect::cmakePresetConfigItem(const Project }); } +void CMakeConfigurationKitAspect::setKitDefaultConfigHash(ProjectExplorer::Kit *k) +{ + const CMakeConfig defaultConfigExpanded + = Utils::transform(defaultConfiguration(k).toList(), [k](const CMakeConfigItem &item) { + CMakeConfigItem expanded(item); + expanded.value = item.expandedValue(k).toUtf8(); + return expanded; + }); + const QByteArray kitHash = computeDefaultConfigHash(defaultConfigExpanded); + + CMakeConfig config = configuration(k); + config.append(CMakeConfigItem(QTC_KIT_DEFAULT_CONFIG_HASH, CMakeConfigItem::INTERNAL, kitHash)); + + setConfiguration(k, config); +} + +CMakeConfigItem CMakeConfigurationKitAspect::kitDefaultConfigHashItem(const ProjectExplorer::Kit *k) +{ + const CMakeConfig config = configuration(k); + return Utils::findOrDefault(config, [](const CMakeConfigItem &item) { + return item.key == QTC_KIT_DEFAULT_CONFIG_HASH; + }); +} + +QByteArray CMakeConfigurationKitAspect::computeDefaultConfigHash(const CMakeConfig &config) +{ + const CMakeConfig defaultConfig = defaultConfiguration(nullptr); + const QByteArray configValues = std::accumulate(defaultConfig.begin(), + defaultConfig.end(), + QByteArray(), + [config](QByteArray &sum, + const CMakeConfigItem &item) { + return sum += config.valueOf(item.key); + }); + return QCryptographicHash::hash(configValues, QCryptographicHash::Md5).toHex(); +} + QVariant CMakeConfigurationKitAspect::defaultValue(const Kit *k) const { // FIXME: Convert preload scripts diff --git a/src/plugins/cmakeprojectmanager/cmakekitinformation.h b/src/plugins/cmakeprojectmanager/cmakekitinformation.h index da2435664b3..25b7b7f3f7d 100644 --- a/src/plugins/cmakeprojectmanager/cmakekitinformation.h +++ b/src/plugins/cmakeprojectmanager/cmakekitinformation.h @@ -91,6 +91,10 @@ public: static void setCMakePreset(ProjectExplorer::Kit *k, const QString &presetName); static CMakeConfigItem cmakePresetConfigItem(const ProjectExplorer::Kit *k); + static void setKitDefaultConfigHash(ProjectExplorer::Kit *k); + static CMakeConfigItem kitDefaultConfigHashItem(const ProjectExplorer::Kit *k); + static QByteArray computeDefaultConfigHash(const CMakeConfig &config); + // KitAspect interface ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *k) const final; void setup(ProjectExplorer::Kit *k) final; diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp index fe9487bbaf6..b2e0e6f12df 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeprojectimporter.cpp @@ -46,6 +46,7 @@ struct DirectoryData QString cmakePresetDisplayname; QString cmakePreset; + QByteArray cmakePresetDefaultConfigHash; // Kit Stuff FilePath cmakeBinary; @@ -549,6 +550,8 @@ QList CMakeProjectImporter::examineDirectory(const FilePath &importPath, CMakeConfigItem::STRING, configurePreset.generator.value().toUtf8()); } + data->cmakePresetDefaultConfigHash = CMakeConfigurationKitAspect::computeDefaultConfigHash( + config); const FilePath qmake = qmakeFromCMakeCache(config); if (!qmake.isEmpty()) @@ -685,8 +688,16 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const bool haveCMakePreset = false; if (!data->cmakePreset.isEmpty()) { - auto presetConfigItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k); - if (data->cmakePreset != presetConfigItem.expandedValue(k)) + const auto presetConfigItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k); + const auto kitConfigHashItem = CMakeConfigurationKitAspect::kitDefaultConfigHashItem(k); + + const QString presetName = presetConfigItem.expandedValue(k); + const bool haveSameKitConfigHash = kitConfigHashItem.isNull() + ? true + : data->cmakePresetDefaultConfigHash + == kitConfigHashItem.value; + + if (data->cmakePreset != presetName || !haveSameKitConfigHash) return false; ensureBuildDirectory(*data, k); @@ -724,15 +735,6 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const CMakeGeneratorKitAspect::setPlatform(k, data->platform); CMakeGeneratorKitAspect::setToolset(k, data->toolset); - if (!data->cmakePresetDisplayname.isEmpty()) { - k->setUnexpandedDisplayName( - QString("%1 (CMake preset)").arg(data->cmakePresetDisplayname)); - - CMakeConfigurationKitAspect::setCMakePreset(k, data->cmakePreset); - } - if (!data->cmakePreset.isEmpty()) - ensureBuildDirectory(*data, k); - SysRootKitAspect::setSysRoot(k, data->sysroot); for (const ToolChainDescription &cmtcd : data->toolChains) { @@ -747,6 +749,16 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const ToolChainKitAspect::setToolChain(k, tcd.tcs.at(0)); } + if (!data->cmakePresetDisplayname.isEmpty()) { + k->setUnexpandedDisplayName( + QString("%1 (CMake preset)").arg(data->cmakePresetDisplayname)); + + CMakeConfigurationKitAspect::setCMakePreset(k, data->cmakePreset); + CMakeConfigurationKitAspect::setKitDefaultConfigHash(k); + } + if (!data->cmakePreset.isEmpty()) + ensureBuildDirectory(*data, k); + qCInfo(cmInputLog) << "Temporary Kit created."; }); }