forked from qt-creator/qt-creator
CMakePM: Add default kit configuration hashing
This adds a QTC_KIT_DEFAULT_CONFIG_HASH variable containing the hash of all the default Qt Creator CMake kit variables: * CMAKE_C_COMPILER * CMAKE_CXX_COMPILER * QT_QMAKE_EXECUTABLE * CMAKE_PREFIX_PATH This way when a CMake preset changes any of these CMake variables a new Kit will be created. Otherwise a previous kit containing different values will be used. Fixes: QTCREATORBUG-28609 Change-Id: I77b67e9c8fa15dc3ff2f22c5b63d4ca1c7670fdc Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
@@ -39,6 +39,7 @@
|
|||||||
#include <utils/variablechooser.h>
|
#include <utils/variablechooser.h>
|
||||||
|
|
||||||
#include <QComboBox>
|
#include <QComboBox>
|
||||||
|
#include <QCryptographicHash>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
#include <QDialogButtonBox>
|
#include <QDialogButtonBox>
|
||||||
#include <QGridLayout>
|
#include <QGridLayout>
|
||||||
@@ -875,6 +876,7 @@ const char CMAKE_CXX_TOOLCHAIN_KEY[] = "CMAKE_CXX_COMPILER";
|
|||||||
const char CMAKE_QMAKE_KEY[] = "QT_QMAKE_EXECUTABLE";
|
const char CMAKE_QMAKE_KEY[] = "QT_QMAKE_EXECUTABLE";
|
||||||
const char CMAKE_PREFIX_PATH_KEY[] = "CMAKE_PREFIX_PATH";
|
const char CMAKE_PREFIX_PATH_KEY[] = "CMAKE_PREFIX_PATH";
|
||||||
const char QTC_CMAKE_PRESET_KEY[] = "QTC_CMAKE_PRESET";
|
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
|
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
|
QVariant CMakeConfigurationKitAspect::defaultValue(const Kit *k) const
|
||||||
{
|
{
|
||||||
// FIXME: Convert preload scripts
|
// FIXME: Convert preload scripts
|
||||||
|
@@ -91,6 +91,10 @@ public:
|
|||||||
static void setCMakePreset(ProjectExplorer::Kit *k, const QString &presetName);
|
static void setCMakePreset(ProjectExplorer::Kit *k, const QString &presetName);
|
||||||
static CMakeConfigItem cmakePresetConfigItem(const ProjectExplorer::Kit *k);
|
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
|
// KitAspect interface
|
||||||
ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *k) const final;
|
ProjectExplorer::Tasks validate(const ProjectExplorer::Kit *k) const final;
|
||||||
void setup(ProjectExplorer::Kit *k) final;
|
void setup(ProjectExplorer::Kit *k) final;
|
||||||
|
@@ -46,6 +46,7 @@ struct DirectoryData
|
|||||||
|
|
||||||
QString cmakePresetDisplayname;
|
QString cmakePresetDisplayname;
|
||||||
QString cmakePreset;
|
QString cmakePreset;
|
||||||
|
QByteArray cmakePresetDefaultConfigHash;
|
||||||
|
|
||||||
// Kit Stuff
|
// Kit Stuff
|
||||||
FilePath cmakeBinary;
|
FilePath cmakeBinary;
|
||||||
@@ -549,6 +550,8 @@ QList<void *> CMakeProjectImporter::examineDirectory(const FilePath &importPath,
|
|||||||
CMakeConfigItem::STRING,
|
CMakeConfigItem::STRING,
|
||||||
configurePreset.generator.value().toUtf8());
|
configurePreset.generator.value().toUtf8());
|
||||||
}
|
}
|
||||||
|
data->cmakePresetDefaultConfigHash = CMakeConfigurationKitAspect::computeDefaultConfigHash(
|
||||||
|
config);
|
||||||
|
|
||||||
const FilePath qmake = qmakeFromCMakeCache(config);
|
const FilePath qmake = qmakeFromCMakeCache(config);
|
||||||
if (!qmake.isEmpty())
|
if (!qmake.isEmpty())
|
||||||
@@ -685,8 +688,16 @@ bool CMakeProjectImporter::matchKit(void *directoryData, const Kit *k) const
|
|||||||
|
|
||||||
bool haveCMakePreset = false;
|
bool haveCMakePreset = false;
|
||||||
if (!data->cmakePreset.isEmpty()) {
|
if (!data->cmakePreset.isEmpty()) {
|
||||||
auto presetConfigItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k);
|
const auto presetConfigItem = CMakeConfigurationKitAspect::cmakePresetConfigItem(k);
|
||||||
if (data->cmakePreset != presetConfigItem.expandedValue(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;
|
return false;
|
||||||
|
|
||||||
ensureBuildDirectory(*data, k);
|
ensureBuildDirectory(*data, k);
|
||||||
@@ -724,15 +735,6 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const
|
|||||||
CMakeGeneratorKitAspect::setPlatform(k, data->platform);
|
CMakeGeneratorKitAspect::setPlatform(k, data->platform);
|
||||||
CMakeGeneratorKitAspect::setToolset(k, data->toolset);
|
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);
|
SysRootKitAspect::setSysRoot(k, data->sysroot);
|
||||||
|
|
||||||
for (const ToolChainDescription &cmtcd : data->toolChains) {
|
for (const ToolChainDescription &cmtcd : data->toolChains) {
|
||||||
@@ -747,6 +749,16 @@ Kit *CMakeProjectImporter::createKit(void *directoryData) const
|
|||||||
ToolChainKitAspect::setToolChain(k, tcd.tcs.at(0));
|
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.";
|
qCInfo(cmInputLog) << "Temporary Kit created.";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user