presets: add support for macro expansion to includes

Only `$penv{}` can be expanded when processing includes.
This commit is contained in:
Zoran Angelov
2023-04-06 20:38:05 +02:00
committed by Brad King
parent 1df24df01f
commit f552ba6e6d
11 changed files with 103 additions and 15 deletions

View File

@@ -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
^^^^^^^^^^^^^^^^

View File

@@ -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.

View File

@@ -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,

View File

@@ -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

View File

@@ -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);

View File

@@ -0,0 +1 @@
1

View File

@@ -0,0 +1,5 @@
^CMake Error: Could not read presets from [^
]*/Tests/RunCMake/CMakePresets/EmptyPenvInInclude:
Error: @3,15: Invalid "include" field
"include": \["\$penv\{\}"\],
\^$

View File

@@ -0,0 +1,11 @@
{
"version": 7,
"include": ["$penv{}"],
"configurePresets": [
{
"name": "EmptyPenvInInclude",
"generator": "@RunCMake_GENERATOR@",
"binaryDir": "${sourceDir}/build"
}
]
}

View File

@@ -0,0 +1,5 @@
^Not searching for unused variables given on the command line\.
Available configure presets:
"Include"
"IncludeCommon"$

View File

@@ -0,0 +1,10 @@
{
"version": 7,
"include": ["$penv{TEST_ENV_INCLUDE_DIR}/IncludeCommon.json"],
"configurePresets": [
{
"name": "Include",
"inherits": ["IncludeCommon"]
}
]
}

View File

@@ -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)