diff options
author | Cristian Adam <cristian.adam@qt.io> | 2023-03-14 14:24:21 +0100 |
---|---|---|
committer | Cristian Adam <cristian.adam@qt.io> | 2023-03-14 14:47:28 +0000 |
commit | 15e1a6476435c0d32fddbdfbd25d7cd00ba64b4a (patch) | |
tree | 9e5762fb82adcfe7afaa8c688466a5ec7a496aaf | |
parent | 25f1a4804aa104955a28535fc66f7529abc18359 (diff) | |
download | qt-creator-15e1a6476435c0d32fddbdfbd25d7cd00ba64b4a.tar.gz |
CMakePM: Add include presets support
Fixes: QTCREATORBUG-28894
Change-Id: I9359cb85c230f2db02f08427af9832f168a32c41
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
-rw-r--r-- | src/plugins/cmakeprojectmanager/cmakeproject.cpp | 39 | ||||
-rw-r--r-- | src/plugins/cmakeprojectmanager/presetsmacros.cpp | 2 | ||||
-rw-r--r-- | src/plugins/cmakeprojectmanager/presetsparser.cpp | 37 | ||||
-rw-r--r-- | src/plugins/cmakeprojectmanager/presetsparser.h | 4 | ||||
-rw-r--r-- | tests/manual/cmakepresets/CMakePresets.json | 122 | ||||
-rw-r--r-- | tests/manual/cmakepresets/mingw.json | 61 | ||||
-rw-r--r-- | tests/manual/cmakepresets/msvc.json | 76 |
7 files changed, 220 insertions, 121 deletions
diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 829c28be15..b0fab0894a 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -208,12 +208,51 @@ void CMakeProject::readPresets() return data; }; + std::function<void(Internal::PresetsData & presetData, Utils::FilePaths & inclueStack)> + resolveIncludes = [&](Internal::PresetsData &presetData, Utils::FilePaths &includeStack) { + if (presetData.include) { + for (const QString &path : presetData.include.value()) { + Utils::FilePath includePath = Utils::FilePath::fromUserInput(path); + if (!includePath.isAbsolutePath()) + includePath = presetData.fileDir.resolvePath(path); + + Internal::PresetsData includeData = parsePreset(includePath); + if (includeData.include) { + if (includeStack.contains(includePath)) { + TaskHub::addTask(BuildSystemTask( + Task::TaskType::Warning, + Tr::tr("Attempt to include %1 which was already parsed.") + .arg(includePath.path()), + Utils::FilePath(), + -1)); + TaskHub::requestPopup(); + } else { + resolveIncludes(includeData, includeStack); + } + } + + presetData.configurePresets = includeData.configurePresets + + presetData.configurePresets; + presetData.buildPresets = includeData.buildPresets + presetData.buildPresets; + + includeStack << includePath; + } + } + }; + const Utils::FilePath cmakePresetsJson = projectDirectory().pathAppended("CMakePresets.json"); const Utils::FilePath cmakeUserPresetsJson = projectDirectory().pathAppended("CMakeUserPresets.json"); Internal::PresetsData cmakePresetsData = parsePreset(cmakePresetsJson); Internal::PresetsData cmakeUserPresetsData = parsePreset(cmakeUserPresetsJson); + // resolve the include + Utils::FilePaths includeStack = {cmakePresetsJson}; + resolveIncludes(cmakePresetsData, includeStack); + + includeStack = {cmakeUserPresetsJson}; + resolveIncludes(cmakeUserPresetsData, includeStack); + m_presetsData = combinePresets(cmakePresetsData, cmakeUserPresetsData); setupBuildPresets(m_presetsData); } diff --git a/src/plugins/cmakeprojectmanager/presetsmacros.cpp b/src/plugins/cmakeprojectmanager/presetsmacros.cpp index 71cff64e1b..98399a7876 100644 --- a/src/plugins/cmakeprojectmanager/presetsmacros.cpp +++ b/src/plugins/cmakeprojectmanager/presetsmacros.cpp @@ -38,6 +38,7 @@ static void expandAllButEnv(const PresetsDetails::ConfigurePreset &preset, value.replace("${sourceDirName}", sourceDirectory.fileName()); value.replace("${presetName}", preset.name); + value.replace("${fileDir}", preset.fileDir.path()); if (preset.generator) value.replace("${generator}", preset.generator.value()); @@ -51,6 +52,7 @@ static void expandAllButEnv(const PresetsDetails::BuildPreset &preset, value.replace("${dollar}", "$"); value.replace("${sourceDir}", sourceDirectory.toString()); + value.replace("${fileDir}", preset.fileDir.path()); value.replace("${sourceParentDir}", sourceDirectory.parentDir().toString()); value.replace("${sourceDirName}", sourceDirectory.fileName()); diff --git a/src/plugins/cmakeprojectmanager/presetsparser.cpp b/src/plugins/cmakeprojectmanager/presetsparser.cpp index 8d1cc1610d..eed174e2b4 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.cpp +++ b/src/plugins/cmakeprojectmanager/presetsparser.cpp @@ -36,6 +36,22 @@ bool parseCMakeMinimumRequired(const QJsonValue &jsonValue, QVersionNumber &vers return true; } +std::optional<QStringList> parseInclude(const QJsonValue &jsonValue) +{ + std::optional<QStringList> includes; + + if (!jsonValue.isUndefined()) { + if (jsonValue.isArray()) { + includes = QStringList(); + const QJsonArray includeArray = jsonValue.toArray(); + for (const QJsonValue &includeValue : includeArray) + includes.value() << includeValue.toString(); + } + } + + return includes; +} + std::optional<PresetsDetails::Condition> parseCondition(const QJsonValue &jsonValue) { std::optional<PresetsDetails::Condition> condition; @@ -133,7 +149,8 @@ std::optional<PresetsDetails::Condition> parseCondition(const QJsonValue &jsonVa } bool parseConfigurePresets(const QJsonValue &jsonValue, - QList<PresetsDetails::ConfigurePreset> &configurePresets) + QList<PresetsDetails::ConfigurePreset> &configurePresets, + const Utils::FilePath &fileDir) { // The whole section is optional if (jsonValue.isUndefined()) @@ -151,6 +168,7 @@ bool parseConfigurePresets(const QJsonValue &jsonValue, PresetsDetails::ConfigurePreset preset; preset.name = object.value("name").toString(); + preset.fileDir = fileDir; preset.hidden = object.value("hidden").toBool(); QJsonValue inherits = object.value("inherits"); @@ -291,7 +309,8 @@ bool parseConfigurePresets(const QJsonValue &jsonValue, } bool parseBuildPresets(const QJsonValue &jsonValue, - QList<PresetsDetails::BuildPreset> &buildPresets) + QList<PresetsDetails::BuildPreset> &buildPresets, + const Utils::FilePath &fileDir) { // The whole section is optional if (jsonValue.isUndefined()) @@ -309,6 +328,7 @@ bool parseBuildPresets(const QJsonValue &jsonValue, PresetsDetails::BuildPreset preset; preset.name = object.value("name").toString(); + preset.fileDir = fileDir; preset.hidden = object.value("hidden").toBool(); QJsonValue inherits = object.value("inherits"); @@ -416,6 +436,8 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage QJsonObject root = jsonDoc.object(); + m_presetsData.fileDir = jsonFile.parentDir(); + if (!parseVersion(root.value("version"), m_presetsData.version)) { errorMessage = Tr::tr("Invalid \"version\" in file \"%1\".").arg(jsonFile.fileName()); return false; @@ -426,14 +448,21 @@ bool PresetsParser::parse(const Utils::FilePath &jsonFile, QString &errorMessage m_presetsData.cmakeMinimimRequired); // optional - if (!parseConfigurePresets(root.value("configurePresets"), m_presetsData.configurePresets)) { + m_presetsData.include = parseInclude(root.value("include")); + + // optional + if (!parseConfigurePresets(root.value("configurePresets"), + m_presetsData.configurePresets, + jsonFile.parentDir())) { errorMessage = Tr::tr("Invalid \"configurePresets\" section in %1 file").arg(jsonFile.fileName()); return false; } // optional - if (!parseBuildPresets(root.value("buildPresets"), m_presetsData.buildPresets)) { + if (!parseBuildPresets(root.value("buildPresets"), + m_presetsData.buildPresets, + jsonFile.parentDir())) { errorMessage = Tr::tr("Invalid \"buildPresets\" section in %1 file").arg(jsonFile.fileName()); return false; diff --git a/src/plugins/cmakeprojectmanager/presetsparser.h b/src/plugins/cmakeprojectmanager/presetsparser.h index 1ee0725a5d..20d36e389e 100644 --- a/src/plugins/cmakeprojectmanager/presetsparser.h +++ b/src/plugins/cmakeprojectmanager/presetsparser.h @@ -90,6 +90,7 @@ public: void inheritFrom(const ConfigurePreset &other); QString name; + Utils::FilePath fileDir; std::optional<bool> hidden = false; std::optional<QStringList> inherits; std::optional<Condition> condition; @@ -115,6 +116,7 @@ public: void inheritFrom(const BuildPreset &other); QString name; + Utils::FilePath fileDir; std::optional<bool> hidden = false; std::optional<QStringList> inherits; std::optional<Condition> condition; @@ -140,6 +142,8 @@ public: int version = 0; QVersionNumber cmakeMinimimRequired; QHash<QString, QString> vendor; + std::optional<QStringList> include; + Utils::FilePath fileDir; QList<PresetsDetails::ConfigurePreset> configurePresets; QList<PresetsDetails::BuildPreset> buildPresets; }; diff --git a/tests/manual/cmakepresets/CMakePresets.json b/tests/manual/cmakepresets/CMakePresets.json index da98c991ba..933e55ff69 100644 --- a/tests/manual/cmakepresets/CMakePresets.json +++ b/tests/manual/cmakepresets/CMakePresets.json @@ -1,93 +1,15 @@ { - "version": 3, + "version": 4, "cmakeMinimumRequired": { "major": 3, - "minor": 21, + "minor": 23, "patch": 0 }, + "include": [ + "mingw.json", "msvc.json" + ], "configurePresets": [ { - "name": "mingw", - "displayName": "MinGW 11.2.0", - "generator": "Ninja", - "installDir": "../inst-${presetName}", - "cacheVariables": { - "CMAKE_PREFIX_PATH": "$env{SYSTEMDRIVE}/Qt/6.4.2/mingw_64" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - }, - "environment": { - "PATH": "$env{SYSTEMDRIVE}/Qt/Tools/mingw1120_64/bin;$penv{PATH}" - }, - "debug" : { - "find" : true - } - }, - { - "name": "mingw-make", - "binaryDir": "${sourceDir}/build-${presetName}-release", - "displayName": "MinGW 11.2.0 Makefiles", - "generator": "MinGW Makefiles", - "inherits" : "mingw", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release", - "CMAKE_PREFIX_PATH": "$env{SystemDrive}/Qt/6.4.2/mingw_64" - } - }, - { - "name": "visualc", - "displayName": "Visual C++ 2019 x64", - "generator": "Visual Studio 16 2019", - "binaryDir": "${sourceDir}/build-${presetName}", - "architecture" : { - "value": "x64" - }, - "toolchainFile" : "../cmakepresets/msvc-toolchain.cmake", - "condition" : { - "type": "not", - "condition": { - "type": "notEquals", - "lhs": "${hostSystemName}", - "rhs": "$env{HOST_SYSTEM_NAME}" - } - }, - "environment" : { - "HOST_SYSTEM_NAME": "Windows", - "QT_VERSION": "6.4.2" - } - }, - { - "name": "visualc-ninja", - "displayName": "Visual C++ 2019 x64 Ninja", - "generator": "Ninja", - "binaryDir": "${sourceDir}/build-${presetName}", - "toolchainFile" : "c:/Qt/6.4.2/msvc2019_64/lib/cmake/Qt6/qt.toolchain.cmake", - "cacheVariables": { - "CMAKE_BUILD_TYPE": "Release" - }, - "condition": { - "type": "equals", - "lhs": "${hostSystemName}", - "rhs": "Windows" - }, - "environment" : { - "VCToolsVersion": "14.29.30133", - "WindowsSDKVersion" : "10.0.22000.0", - "VCArch": "x64", - "VCToolsInstallDir": "$env{ProgramFiles(x86)}/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/$env{VCToolsVersion}", - "WindowsSdkDir" : "$env{ProgramFiles(x86)}/Windows Kits/10", - "WindowsSdkIncVerDir": "$env{WindowsSdkDir}/Include/$env{WindowsSDKVersion}", - "WindowsSdkLibVerDir": "$env{WindowsSdkDir}/Lib/$env{WindowsSDKVersion}", - - "INCLUDE": "$env{VCToolsInstallDir}/ATLMFC/include;$env{VCToolsInstallDir}/include;$env{WindowsSdkIncVerDir}/ucrt;$env{WindowsSdkIncVerDir}/shared;$env{WindowsSdkIncVerDir}/um;$env{WindowsSdkIncVerDir}/winrt;$env{WindowsSdkIncVerDir}/cppwinrt", - "LIB": "$env{VCToolsInstallDir}/ATLMFC/lib/$env{VCArch};$env{VCToolsInstallDir}/lib/$env{VCArch};$env{WindowsSdkLibVerDir}/ucrt/$env{VCArch};$env{WindowsSdkLibVerDir}/um/$env{VCArch}", - "PATH": "$env{VCToolsInstallDir}/bin/HostX64/$env{VCArch};$env{WindowsSdkDir}/bin/$env{WindowsSDKVersion}/$env{VCArch};$penv{PATH}" - } - }, - { "name": "linux-gcc", "displayName": "Linux GCC", "generator": "Ninja", @@ -99,39 +21,5 @@ "rhs": "Linux" } } - ], - "buildPresets": [ - { - "name": "mingw", - "displayName": "MinGW default", - "configurePreset": "mingw", - "targets": "${sourceDirName}" - }, - { - "name": "mingw-verbose", - "inherits": "mingw", - "displayName": "MinGW verbose", - "verbose": true - }, - { - "name": "mingw-make", - "displayName": "MinGW make 4 CPUs", - "configurePreset": "mingw-make", - "jobs": 4 - }, - { - "name": "visualc-debug", - "configurePreset": "visualc", - "configuration": "Debug" - }, - { - "name": "visualc-relwithdebinfo", - "inherits": "visualc-debug", - "configuration": "RelWithDebInfo" - }, - { - "name": "visualc-ninja", - "configurePreset": "visualc-ninja" - } ] } diff --git a/tests/manual/cmakepresets/mingw.json b/tests/manual/cmakepresets/mingw.json new file mode 100644 index 0000000000..01a240f716 --- /dev/null +++ b/tests/manual/cmakepresets/mingw.json @@ -0,0 +1,61 @@ +{ + "version": 4, + "cmakeMinimumRequired": { + "major": 3, + "minor": 23, + "patch": 0 + }, + "configurePresets": [ + { + "name": "mingw", + "displayName": "MinGW 11.2.0", + "generator": "Ninja", + "installDir": "../inst-${presetName}", + "cacheVariables": { + "CMAKE_PREFIX_PATH": "$env{SYSTEMDRIVE}/Qt/6.4.2/mingw_64" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "environment": { + "PATH": "$env{SYSTEMDRIVE}/Qt/Tools/mingw1120_64/bin;$penv{PATH}" + }, + "debug" : { + "find" : true + } + }, + { + "name": "mingw-make", + "binaryDir": "${sourceDir}/build-${presetName}-release", + "displayName": "MinGW 11.2.0 Makefiles", + "generator": "MinGW Makefiles", + "inherits" : "mingw", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release", + "CMAKE_PREFIX_PATH": "$env{SystemDrive}/Qt/6.4.2/mingw_64" + } + } + ], + "buildPresets": [ + { + "name": "mingw", + "displayName": "MinGW default", + "configurePreset": "mingw", + "targets": "${sourceDirName}" + }, + { + "name": "mingw-verbose", + "inherits": "mingw", + "displayName": "MinGW verbose", + "verbose": true + }, + { + "name": "mingw-make", + "displayName": "MinGW make 4 CPUs", + "configurePreset": "mingw-make", + "jobs": 4 + } + ] +} diff --git a/tests/manual/cmakepresets/msvc.json b/tests/manual/cmakepresets/msvc.json new file mode 100644 index 0000000000..5f4c9b4c5d --- /dev/null +++ b/tests/manual/cmakepresets/msvc.json @@ -0,0 +1,76 @@ +{ + "version": 4, + "cmakeMinimumRequired": { + "major": 3, + "minor": 23, + "patch": 0 + }, + "configurePresets": [ + { + "name": "visualc", + "displayName": "Visual C++ 2019 x64", + "generator": "Visual Studio 16 2019", + "binaryDir": "${sourceDir}/build-${presetName}", + "architecture" : { + "value": "x64" + }, + "toolchainFile" : "../cmakepresets/msvc-toolchain.cmake", + "condition" : { + "type": "not", + "condition": { + "type": "notEquals", + "lhs": "${hostSystemName}", + "rhs": "$env{HOST_SYSTEM_NAME}" + } + }, + "environment" : { + "HOST_SYSTEM_NAME": "Windows", + "QT_VERSION": "6.4.2" + } + }, + { + "name": "visualc-ninja", + "displayName": "Visual C++ 2019 x64 Ninja", + "generator": "Ninja", + "binaryDir": "${sourceDir}/build-${presetName}", + "toolchainFile" : "c:/Qt/6.4.2/msvc2019_64/lib/cmake/Qt6/qt.toolchain.cmake", + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + }, + "condition": { + "type": "equals", + "lhs": "${hostSystemName}", + "rhs": "Windows" + }, + "environment" : { + "VCToolsVersion": "14.29.30133", + "WindowsSDKVersion" : "10.0.22000.0", + "VCArch": "x64", + "VCToolsInstallDir": "$env{ProgramFiles(x86)}/Microsoft Visual Studio/2019/Professional/VC/Tools/MSVC/$env{VCToolsVersion}", + "WindowsSdkDir" : "$env{ProgramFiles(x86)}/Windows Kits/10", + "WindowsSdkIncVerDir": "$env{WindowsSdkDir}/Include/$env{WindowsSDKVersion}", + "WindowsSdkLibVerDir": "$env{WindowsSdkDir}/Lib/$env{WindowsSDKVersion}", + + "INCLUDE": "$env{VCToolsInstallDir}/ATLMFC/include;$env{VCToolsInstallDir}/include;$env{WindowsSdkIncVerDir}/ucrt;$env{WindowsSdkIncVerDir}/shared;$env{WindowsSdkIncVerDir}/um;$env{WindowsSdkIncVerDir}/winrt;$env{WindowsSdkIncVerDir}/cppwinrt", + "LIB": "$env{VCToolsInstallDir}/ATLMFC/lib/$env{VCArch};$env{VCToolsInstallDir}/lib/$env{VCArch};$env{WindowsSdkLibVerDir}/ucrt/$env{VCArch};$env{WindowsSdkLibVerDir}/um/$env{VCArch}", + "PATH": "$env{VCToolsInstallDir}/bin/HostX64/$env{VCArch};$env{WindowsSdkDir}/bin/$env{WindowsSDKVersion}/$env{VCArch};$penv{PATH}" + } + } + ], + "buildPresets": [ + { + "name": "visualc-debug", + "configurePreset": "visualc", + "configuration": "Debug" + }, + { + "name": "visualc-relwithdebinfo", + "inherits": "visualc-debug", + "configuration": "RelWithDebInfo" + }, + { + "name": "visualc-ninja", + "configurePreset": "visualc-ninja" + } + ] +} |