diff options
author | Zoran Angelov <baldzar@gmail.com> | 2023-04-06 18:38:05 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2023-04-26 14:03:53 (GMT) |
commit | f552ba6e6d4571213afdc8afdd063637ac0cbee7 (patch) | |
tree | 7498447afb89df59d600eab0dff0b221bb210bd1 | |
parent | 1df24df01f0053d07ac2083c4ea8fa915cbb5e65 (diff) | |
download | CMake-f552ba6e6d4571213afdc8afdd063637ac0cbee7.zip CMake-f552ba6e6d4571213afdc8afdd063637ac0cbee7.tar.gz CMake-f552ba6e6d4571213afdc8afdd063637ac0cbee7.tar.bz2 |
presets: add support for macro expansion to includes
Only `$penv{}` can be expanded when processing includes.
-rw-r--r-- | Help/manual/cmake-presets.7.rst | 3 | ||||
-rw-r--r-- | Help/release/dev/preset-includes-macro-expansion.rst | 7 | ||||
-rw-r--r-- | Source/cmCMakePresetsGraph.cxx | 22 | ||||
-rw-r--r-- | Source/cmCMakePresetsGraphInternal.h | 10 | ||||
-rw-r--r-- | Source/cmCMakePresetsGraphReadJSON.cxx | 37 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt | 1 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt | 5 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in | 11 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt | 5 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/IncludeExpansion.json.in | 10 | ||||
-rw-r--r-- | Tests/RunCMake/CMakePresets/RunCMakeTest.cmake | 7 |
11 files changed, 103 insertions, 15 deletions
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst index 7aea8e6..e2366da 100644 --- a/Help/manual/cmake-presets.7.rst +++ b/Help/manual/cmake-presets.7.rst @@ -133,6 +133,9 @@ Files directly or indirectly included from ``CMakePresets.json`` should be guaranteed to be provided by the project. ``CMakeUserPresets.json`` may include files from anywhere. +Starting from version ``7``, the ``include`` field supports +`macro expansion`_, but only ``$penv{}`` macro expansion. + Configure Preset ^^^^^^^^^^^^^^^^ diff --git a/Help/release/dev/preset-includes-macro-expansion.rst b/Help/release/dev/preset-includes-macro-expansion.rst new file mode 100644 index 0000000..e1f0030 --- /dev/null +++ b/Help/release/dev/preset-includes-macro-expansion.rst @@ -0,0 +1,7 @@ +preset-includes-macro-expansion +------------------------------- + +* :manual:`cmake-presets(7)` files now support schema version ``7``. + +* :manual:`cmake-presets(7)` now supports ``$penv{}`` macro expansion + in ``include`` fields. diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx index f9b263a..13eddbe 100644 --- a/Source/cmCMakePresetsGraph.cxx +++ b/Source/cmCMakePresetsGraph.cxx @@ -48,6 +48,7 @@ template <typename T> using PresetPair = cmCMakePresetsGraph::PresetPair<T>; using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult; using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander; +using cmCMakePresetsGraphInternal::ExpandMacros; void InheritString(std::string& child, const std::string& parent) { @@ -203,14 +204,6 @@ bool IsValidMacroNamespace(const std::string& str) ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status, const std::vector<MacroExpander>& macroExpanders, int version); -ExpandMacroResult ExpandMacros( - std::string& out, const std::vector<MacroExpander>& macroExpanders, - int version); -ExpandMacroResult ExpandMacro(std::string& out, - const std::string& macroNamespace, - const std::string& macroName, - const std::vector<MacroExpander>& macroExpanders, - int version); bool ExpandMacros(const cmCMakePresetsGraph& graph, const ConfigurePreset& preset, @@ -514,8 +507,9 @@ ExpandMacroResult VisitEnv(std::string& value, CycleStatus& status, status = CycleStatus::Verified; return ExpandMacroResult::Ok; } +} -ExpandMacroResult ExpandMacros( +ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacros( std::string& out, const std::vector<MacroExpander>& macroExpanders, int version) { @@ -594,11 +588,10 @@ ExpandMacroResult ExpandMacros( return ExpandMacroResult::Ok; } -ExpandMacroResult ExpandMacro(std::string& out, - const std::string& macroNamespace, - const std::string& macroName, - const std::vector<MacroExpander>& macroExpanders, - int version) +ExpandMacroResult cmCMakePresetsGraphInternal::ExpandMacro( + std::string& out, const std::string& macroNamespace, + const std::string& macroName, + const std::vector<MacroExpander>& macroExpanders, int version) { for (auto const& macroExpander : macroExpanders) { auto result = macroExpander(macroNamespace, macroName, out, version); @@ -614,6 +607,7 @@ ExpandMacroResult ExpandMacro(std::string& out, return ExpandMacroResult::Error; } +namespace { template <typename T> bool SetupWorkflowConfigurePreset(const T& preset, const ConfigurePreset*& configurePreset, diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h index db784c3..f133efb 100644 --- a/Source/cmCMakePresetsGraphInternal.h +++ b/Source/cmCMakePresetsGraphInternal.h @@ -28,6 +28,16 @@ enum class ExpandMacroResult using MacroExpander = std::function<ExpandMacroResult( const std::string&, const std::string&, std::string&, int version)>; + +ExpandMacroResult ExpandMacros( + std::string& out, const std::vector<MacroExpander>& macroExpanders, + int version); + +ExpandMacroResult ExpandMacro(std::string& out, + const std::string& macroNamespace, + const std::string& macroName, + const std::vector<MacroExpander>& macroExpanders, + int version); } class cmCMakePresetsGraph::Condition diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx index bc829f3..54fea40 100644 --- a/Source/cmCMakePresetsGraphReadJSON.cxx +++ b/Source/cmCMakePresetsGraphReadJSON.cxx @@ -33,6 +33,9 @@ using PackagePreset = cmCMakePresetsGraph::PackagePreset; using WorkflowPreset = cmCMakePresetsGraph::WorkflowPreset; using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy; using JSONHelperBuilder = cmJSONHelperBuilder; +using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult; +using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander; +using cmCMakePresetsGraphInternal::ExpandMacros; constexpr int MIN_VERSION = 1; constexpr int MAX_VERSION = 7; @@ -688,7 +691,39 @@ bool cmCMakePresetsGraph::ReadJSONFile(const std::string& filename, return true; }; - for (auto include : presets.Include) { + std::vector<MacroExpander> macroExpanders; + + MacroExpander environmentMacroExpander = + [](const std::string& macroNamespace, const std::string& macroName, + std::string& expanded, int /*version*/) -> ExpandMacroResult { + if (macroNamespace == "penv") { + if (macroName.empty()) { + return ExpandMacroResult::Error; + } + if (cm::optional<std::string> value = + cmSystemTools::GetEnvVar(macroName)) { + expanded += *value; + } + return ExpandMacroResult::Ok; + } + + return ExpandMacroResult::Ignore; + }; + + macroExpanders.push_back(environmentMacroExpander); + + for (Json::ArrayIndex i = 0; i < presets.Include.size(); ++i) { + auto include = presets.Include[i]; + + // Support for macro expansion in includes added in version 7 + if (v >= 7) { + if (ExpandMacros(include, macroExpanders, v) != ExpandMacroResult::Ok) { + cmCMakePresetErrors::INVALID_INCLUDE(&root["include"][i], + &this->parseState); + return false; + } + } + if (!cmSystemTools::FileIsFullPath(include)) { auto directory = cmSystemTools::GetFilenamePath(filename); include = cmStrCat(directory, '/', include); diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt new file mode 100644 index 0000000..e0f858a --- /dev/null +++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude-stderr.txt @@ -0,0 +1,5 @@ +^CMake Error: Could not read presets from [^ +]*/Tests/RunCMake/CMakePresets/EmptyPenvInInclude: +Error: @3,15: Invalid "include" field + "include": \["\$penv\{\}"\], + \^$ diff --git a/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in new file mode 100644 index 0000000..651b0de --- /dev/null +++ b/Tests/RunCMake/CMakePresets/EmptyPenvInInclude.json.in @@ -0,0 +1,11 @@ +{ + "version": 7, + "include": ["$penv{}"], + "configurePresets": [ + { + "name": "EmptyPenvInInclude", + "generator": "@RunCMake_GENERATOR@", + "binaryDir": "${sourceDir}/build" + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt b/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt new file mode 100644 index 0000000..d3f1afc --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeExpansion-stdout.txt @@ -0,0 +1,5 @@ +^Not searching for unused variables given on the command line\. +Available configure presets: + + "Include" + "IncludeCommon"$ diff --git a/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in b/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in new file mode 100644 index 0000000..b4f8292 --- /dev/null +++ b/Tests/RunCMake/CMakePresets/IncludeExpansion.json.in @@ -0,0 +1,10 @@ +{ + "version": 7, + "include": ["$penv{TEST_ENV_INCLUDE_DIR}/IncludeCommon.json"], + "configurePresets": [ + { + "name": "Include", + "inherits": ["IncludeCommon"] + } + ] +} diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake index d67e8b1..c4a8b3f 100644 --- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake +++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake @@ -146,6 +146,7 @@ run_cmake_presets(NoSuchMacro) run_cmake_presets(EnvCycle) run_cmake_presets(EmptyEnv) run_cmake_presets(EmptyPenv) +run_cmake_presets(EmptyPenvInInclude) run_cmake_presets(InvalidRegex) set(CMakePresets_SCHEMA_EXPECTED_RESULT 1) run_cmake_presets(ConditionFuture) @@ -393,6 +394,12 @@ set(CMakePresets_EXTRA_FILES "${RunCMake_SOURCE_DIR}/subdir/CMakePresets.json.in" ) run_cmake_presets(Include --list-presets) +set(CMakePresets_EXTRA_FILES + "${RunCMake_SOURCE_DIR}/IncludeCommon.json.in" + ) +set(ENV{TEST_ENV_INCLUDE_DIR} ${RunCMake_BINARY_DIR}/IncludeExpansion) +run_cmake_presets(IncludeExpansion --list-presets) +unset(ENV{TEST_ENV_INCLUDE_DIR}) unset(CMakePresets_EXTRA_FILES) run_cmake_presets(IncludeNotFound) run_cmake_presets(IncludeCycle) |