diff options
-rw-r--r-- | Help/manual/cmake-presets.7.rst | 8 | ||||
-rw-r--r-- | Help/manual/presets/schema.json | 5 | ||||
-rw-r--r-- | Source/cmCMakePresetsFile.cxx | 10 | ||||
-rw-r--r-- | Source/cmCMakePresetsFile.h | 2 | ||||
-rw-r--r-- | Source/cmCMakePresetsFileReadJSON.cxx | 7 | ||||
-rw-r--r-- | Source/cmake.cxx | 7 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/FuturePresetToolchainField-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt | 2 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/FuturePresetToolchainField.json.in | 11 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/GoodToolchain.json.in | 30 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/GoodToolchainCommandLine.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/GoodToolchainDefault.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/GoodToolchainInherit.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/GoodToolchainOverride.cmake | 3 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/RunCMakeTest.cmake | 36 |
15 files changed, 129 insertions, 2 deletions
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst index 3714004..57c8ccf 100644 --- a/Help/manual/cmake-presets.7.rst +++ b/Help/manual/cmake-presets.7.rst @@ -182,6 +182,14 @@ that may contain the following fields: ignore the field, but the IDE can use them to set up the environment before invoking CMake. +``toolchainFile`` + + An optional string representing the path to the toolchain file. + This field supports `macro expansion`_. If a relative path is specified, + it is calculated relative to the build directory, and if not found, + relative to the source directory. Takes precedence over any `CMAKE_TOOLCHAIN_FILE` + value. This is allowed in preset files specifying version ``3`` or above. + ``binaryDir`` An optional string representing the path to the output binary directory. diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json index e066362..0d51b1f 100644 --- a/Help/manual/presets/schema.json +++ b/Help/manual/presets/schema.json @@ -87,6 +87,10 @@ "type": "string", "description": "An optional string representing the generator to use for the preset. If generator is not specified, the normal generator discovery procedure is used. Note that for Visual Studio generators, unlike in the command line -G argument, you cannot include the platform name in the generator name. Use the architecture field instead." }, + "toolchainFile": { + "type": "string", + "description": "An optional string representing the path to the toolchain file. This field supports macro expansion. If a relative path is specified, it is calculated relative to the build directory, and if not found, relative to the source directory." + }, "installDir": { "type": "string", "description": "An optional string representing the path to the output binary directory. This field supports macro expansion. If a relative path is specified, it is calculated relative to the source directory. If binaryDir is not specified, it must be inherited from the inherits preset (unless this preset is hidden)." @@ -360,6 +364,7 @@ "generator": {}, "architecture": {}, "toolset": {}, + "toolchainFile": {}, "binaryDir": {}, "installDir": {}, "cmakeExecutable": {}, diff --git a/Source/cmCMakePresetsFile.cxx b/Source/cmCMakePresetsFile.cxx index 39cce98..2f9972c 100644 --- a/Source/cmCMakePresetsFile.cxx +++ b/Source/cmCMakePresetsFile.cxx @@ -214,6 +214,12 @@ bool ExpandMacros(const cmCMakePresetsFile& file, cmSystemTools::ConvertToUnixSlashes(out->InstallDir); } + if (!preset.ToolchainFile.empty()) { + std::string toolchain = preset.ToolchainFile; + CHECK_EXPAND(out, toolchain, macroExpanders, file.GetVersion(preset)) + out->ToolchainFile = toolchain; + } + for (auto& variable : out->CacheVariables) { if (variable.second) { CHECK_EXPAND(out, variable.second->Value, macroExpanders, @@ -643,6 +649,7 @@ cmCMakePresetsFile::ConfigurePreset::VisitPresetInherit( } InheritString(preset.BinaryDir, parent.BinaryDir); InheritString(preset.InstallDir, parent.InstallDir); + InheritString(preset.ToolchainFile, parent.ToolchainFile); InheritOptionalValue(preset.WarnDev, parent.WarnDev); InheritOptionalValue(preset.ErrorDev, parent.ErrorDev); InheritOptionalValue(preset.WarnDeprecated, parent.WarnDeprecated); @@ -989,6 +996,9 @@ const char* cmCMakePresetsFile::ResultToString(ReadFileResult result) return "Invalid preset condition"; case ReadFileResult::CONDITION_UNSUPPORTED: return "File version must be 3 or higher for condition support"; + case ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED: + return "File version must be 3 or higher for toolchainFile preset " + "support."; } return "Unknown error"; diff --git a/Source/cmCMakePresetsFile.h b/Source/cmCMakePresetsFile.h index fc14830..7aa9b6a 100644 --- a/Source/cmCMakePresetsFile.h +++ b/Source/cmCMakePresetsFile.h @@ -39,6 +39,7 @@ public: INSTALL_PREFIX_UNSUPPORTED, INVALID_CONDITION, CONDITION_UNSUPPORTED, + TOOLCHAIN_FILE_UNSUPPORTED, }; enum class ArchToolsetStrategy @@ -113,6 +114,7 @@ public: cm::optional<ArchToolsetStrategy> ArchitectureStrategy; std::string Toolset; cm::optional<ArchToolsetStrategy> ToolsetStrategy; + std::string ToolchainFile; std::string BinaryDir; std::string InstallDir; diff --git a/Source/cmCMakePresetsFileReadJSON.cxx b/Source/cmCMakePresetsFileReadJSON.cxx index 403fac6..909a78b 100644 --- a/Source/cmCMakePresetsFileReadJSON.cxx +++ b/Source/cmCMakePresetsFileReadJSON.cxx @@ -491,6 +491,8 @@ auto const ConfigurePresetHelper = false) .Bind("architecture"_s, ArchitectureHelper, false) .Bind("toolset"_s, ToolsetHelper, false) + .Bind("toolchainFile"_s, &ConfigurePreset::ToolchainFile, + PresetStringHelper, false) .Bind("binaryDir"_s, &ConfigurePreset::BinaryDir, PresetStringHelper, false) .Bind("installDir"_s, &ConfigurePreset::InstallDir, PresetStringHelper, @@ -973,6 +975,11 @@ cmCMakePresetsFile::ReadFileResult cmCMakePresetsFile::ReadJSONFile( return ReadFileResult::CONDITION_UNSUPPORTED; } + // Support for toolchainFile presets added in version 3. + if (v < 3 && !preset.ToolchainFile.empty()) { + return ReadFileResult::TOOLCHAIN_FILE_UNSUPPORTED; + } + this->ConfigurePresetOrder.push_back(preset.Name); } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index d24e268..4130f5f 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1257,6 +1257,13 @@ void cmake::SetArgs(const std::vector<std::string>& args) "PATH", expandedPreset->InstallDir }; } + if (!expandedPreset->ToolchainFile.empty() && + this->State->GetInitializedCacheValue("CMAKE_TOOLCHAIN_FILE") == + nullptr) { + this->UnprocessedPresetVariables["CMAKE_TOOLCHAIN_FILE"] = { + "FILEPATH", expandedPreset->ToolchainFile + }; + } if (!expandedPreset->ArchitectureStrategy || expandedPreset->ArchitectureStrategy == diff --git a/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-result.txt b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt new file mode 100644 index 0000000..9382423 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField-stderr.txt @@ -0,0 +1,2 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/FuturePresetToolchainField: File version must be 3 or higher for toolchainFile preset support.$ diff --git a/Tests/RunCMake/CMakePresets/FuturePresetToolchainField.json.in b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField.json.in new file mode 100644 index 0000000..646ee0f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/FuturePresetToolchainField.json.in @@ -0,0 +1,11 @@ +{ + "version": 1, + "configurePresets": [ + { + "name": "FuturePresetToolchainField", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build", + "toolchainFile": "${sourceDir}/toolchain.cmake" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodToolchain.json.in b/Tests/RunCMake/CMakePresets/GoodToolchain.json.in new file mode 100644 index 0000000..69dafcf --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchain.json.in @@ -0,0 +1,30 @@ +{ + "version": 3, + "configurePresets": [ + { + "name": "GoodToolchainDefault", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build/${presetName}", + "toolchainFile": "${sourceDir}/toolchain.cmake" + }, + { + "name": "GoodToolchainInherit", + "inherits": "GoodToolchainDefault", + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": { + "type": "FILEPATH", + "value": "${sourceDir}/toolchain_bad.cmake" + } + } + }, + { + "name": "GoodToolchainOverride", + "inherits": "GoodToolchainInherit", + "toolchainFile": "override_toolchain.cmake" + }, + { + "name": "GoodToolchainCommandLine", + "inherits": "GoodToolchainOverride" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/GoodToolchainCommandLine.cmake b/Tests/RunCMake/CMakePresets/GoodToolchainCommandLine.cmake new file mode 100644 index 0000000..c37421c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchainCommandLine.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_TOOLCHAIN_FILE" "FILEPATH" "${CMAKE_SOURCE_DIR}/cmd_line_toolchain.cmake") diff --git a/Tests/RunCMake/CMakePresets/GoodToolchainDefault.cmake b/Tests/RunCMake/CMakePresets/GoodToolchainDefault.cmake new file mode 100644 index 0000000..53c938b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchainDefault.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_TOOLCHAIN_FILE" "FILEPATH" "${CMAKE_SOURCE_DIR}/toolchain.cmake") diff --git a/Tests/RunCMake/CMakePresets/GoodToolchainInherit.cmake b/Tests/RunCMake/CMakePresets/GoodToolchainInherit.cmake new file mode 100644 index 0000000..53c938b --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchainInherit.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_TOOLCHAIN_FILE" "FILEPATH" "${CMAKE_SOURCE_DIR}/toolchain.cmake") diff --git a/Tests/RunCMake/CMakePresets/GoodToolchainOverride.cmake b/Tests/RunCMake/CMakePresets/GoodToolchainOverride.cmake new file mode 100644 index 0000000..558134c --- /dev/null +++ b/Tests/RunCMake/CMakePresets/GoodToolchainOverride.cmake @@ -0,0 +1,3 @@ +include("${RunCMake_SOURCE_DIR}/TestVariable.cmake") + +test_variable("CMAKE_TOOLCHAIN_FILE" "FILEPATH" "${CMAKE_SOURCE_DIR}/override_toolchain.cmake") diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake index bcbd177..02051d9 100644 --- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake @@ -11,14 +11,23 @@ set(RunCMake-check-file check.cmake) include("${RunCMake_SOURCE_DIR}/validate_schema.cmake") +function(reset_cmake_presets_directory name) + set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}") + file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}") +endfunction() + function(run_cmake_presets name) set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}") set(_source_arg "${RunCMake_TEST_SOURCE_DIR}") if(CMakePresets_SOURCE_ARG) set(_source_arg "${CMakePresets_SOURCE_ARG}") endif() - file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") - file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}") + + if(NOT RunCMake_TEST_SOURCE_DIR_NO_CLEAN) + file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}") + file(MAKE_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}") + endif() configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY) if(NOT CMakePresets_FILE) @@ -95,6 +104,7 @@ run_cmake_presets(ExtraRootField) run_cmake_presets(ExtraPresetField) run_cmake_presets(ExtraVariableField) run_cmake_presets(FuturePresetInstallDirField) +run_cmake_presets(FuturePresetToolchainField) run_cmake_presets(InvalidPresetVendor) set(CMakePresets_SCHEMA_EXPECTED_RESULT 0) run_cmake_presets(DuplicatePresets) @@ -191,6 +201,28 @@ run_cmake_presets(GoodInstallInherit) run_cmake_presets(GoodInstallOverride) run_cmake_presets(GoodInstallCommandLine "--install-prefix=${RunCMake_SOURCE_DIR}/path/passed/on/command_line") +set(RunCMake_TEST_SOURCE_DIR_NO_CLEAN 1) +set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/GoodToolchain.json.in") + +reset_cmake_presets_directory(GoodToolchainInherit) +file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainDefault/toolchain.cmake" "") +run_cmake_presets(GoodToolchainDefault) + +reset_cmake_presets_directory(GoodToolchainInherit) +file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainInherit/toolchain.cmake" "") +run_cmake_presets(GoodToolchainInherit) + +reset_cmake_presets_directory(GoodToolchainOverride) +file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainOverride/override_toolchain.cmake" "") +run_cmake_presets(GoodToolchainOverride) + +reset_cmake_presets_directory(GoodToolchainCommandLine) +file(WRITE "${RunCMake_BINARY_DIR}/GoodToolchainCommandLine/cmd_line_toolchain.cmake" "") +run_cmake_presets(GoodToolchainCommandLine "--toolchain=${RunCMake_BINARY_DIR}/GoodToolchainCommandLine/cmd_line_toolchain.cmake") + +unset(RunCMake_TEST_SOURCE_DIR_NO_CLEAN) + + set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/CMakePresets.json.in") # Test bad preset arguments run_cmake_presets(VendorMacro) |