Merge topic 'preset-includes-macro-expansion'

f552ba6e6d presets: add support for macro expansion to includes
1df24df01f presets: Fix encoding of env/penv macro expansion on Windows

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !8255
This commit is contained in:
Brad King
2023-04-27 13:04:54 +00:00
committed by Kitware Robot
11 changed files with 106 additions and 19 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

@@ -4,7 +4,6 @@
#include <algorithm>
#include <cassert>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <iterator>
@@ -49,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)
{
@@ -204,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,
@@ -448,9 +440,9 @@ bool ExpandMacros(cmCMakePresetsGraph& graph, const T& preset,
if (macroName.empty()) {
return ExpandMacroResult::Error;
}
const char* value = std::getenv(macroName.c_str());
if (value) {
result += value;
if (cm::optional<std::string> value =
cmSystemTools::GetEnvVar(macroName)) {
result += *value;
}
return ExpandMacroResult::Ok;
}
@@ -515,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)
{
@@ -595,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);
@@ -615,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)