mirror of
https://github.com/Kitware/CMake.git
synced 2025-12-31 02:39:48 -06:00
PATH-genex: handle lists for path decomposition and transformations
Fixes: #24371
This commit is contained in:
@@ -446,16 +446,20 @@ command. All paths are expected to be in cmake-style format.
|
||||
components from a path. See :ref:`Path Structure And Terminology` for the
|
||||
meaning of each path component.
|
||||
|
||||
.. versionchanged:: 3.27
|
||||
All operations now accept a list of paths as argument. When a list of paths
|
||||
is specified, the operation will be applied to each path.
|
||||
|
||||
::
|
||||
|
||||
$<PATH:GET_ROOT_NAME,path>
|
||||
$<PATH:GET_ROOT_DIRECTORY,path>
|
||||
$<PATH:GET_ROOT_PATH,path>
|
||||
$<PATH:GET_FILENAME,path>
|
||||
$<PATH:GET_EXTENSION[,LAST_ONLY],path>
|
||||
$<PATH:GET_STEM[,LAST_ONLY],path>
|
||||
$<PATH:GET_RELATIVE_PART,path>
|
||||
$<PATH:GET_PARENT_PATH,path>
|
||||
$<PATH:GET_ROOT_NAME,path...>
|
||||
$<PATH:GET_ROOT_DIRECTORY,path...>
|
||||
$<PATH:GET_ROOT_PATH,path...>
|
||||
$<PATH:GET_FILENAME,path...>
|
||||
$<PATH:GET_EXTENSION[,LAST_ONLY],path...>
|
||||
$<PATH:GET_STEM[,LAST_ONLY],path...>
|
||||
$<PATH:GET_RELATIVE_PART,path...>
|
||||
$<PATH:GET_PARENT_PATH,path...>
|
||||
|
||||
If a requested component is not present in the path, an empty string is
|
||||
returned.
|
||||
@@ -470,9 +474,14 @@ These expressions provide the generation-time capabilities equivalent to the
|
||||
options of the :command:`cmake_path` command. All paths are expected to be
|
||||
in cmake-style format.
|
||||
|
||||
.. versionchanged:: 3.27
|
||||
All operations now accept a list of paths as argument. When a list of paths
|
||||
is specified, the operation will be applied to each path.
|
||||
|
||||
|
||||
.. _GenEx PATH-CMAKE_PATH:
|
||||
|
||||
.. genex:: $<PATH:CMAKE_PATH[,NORMALIZE],path>
|
||||
.. genex:: $<PATH:CMAKE_PATH[,NORMALIZE],path...>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
@@ -483,7 +492,7 @@ in cmake-style format.
|
||||
When the ``NORMALIZE`` option is specified, the path is :ref:`normalized
|
||||
<Normalization>` after the conversion.
|
||||
|
||||
.. genex:: $<PATH:APPEND,path,input,...>
|
||||
.. genex:: $<PATH:APPEND,path...,input,...>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
@@ -493,7 +502,7 @@ in cmake-style format.
|
||||
|
||||
See :ref:`cmake_path(APPEND) <APPEND>` for more details.
|
||||
|
||||
.. genex:: $<PATH:REMOVE_FILENAME,path>
|
||||
.. genex:: $<PATH:REMOVE_FILENAME,path...>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
@@ -503,7 +512,7 @@ in cmake-style format.
|
||||
|
||||
See :ref:`cmake_path(REMOVE_FILENAME) <REMOVE_FILENAME>` for more details.
|
||||
|
||||
.. genex:: $<PATH:REPLACE_FILENAME,path,input>
|
||||
.. genex:: $<PATH:REPLACE_FILENAME,path...,input>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
@@ -513,7 +522,7 @@ in cmake-style format.
|
||||
|
||||
See :ref:`cmake_path(REPLACE_FILENAME) <REPLACE_FILENAME>` for more details.
|
||||
|
||||
.. genex:: $<PATH:REMOVE_EXTENSION[,LAST_ONLY],path>
|
||||
.. genex:: $<PATH:REMOVE_EXTENSION[,LAST_ONLY],path...>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
@@ -521,7 +530,7 @@ in cmake-style format.
|
||||
|
||||
See :ref:`cmake_path(REMOVE_EXTENSION) <REMOVE_EXTENSION>` for more details.
|
||||
|
||||
.. genex:: $<PATH:REPLACE_EXTENSION[,LAST_ONLY],path,input>
|
||||
.. genex:: $<PATH:REPLACE_EXTENSION[,LAST_ONLY],path...,input>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
@@ -530,14 +539,14 @@ in cmake-style format.
|
||||
|
||||
See :ref:`cmake_path(REPLACE_EXTENSION) <REPLACE_EXTENSION>` for more details.
|
||||
|
||||
.. genex:: $<PATH:NORMAL_PATH,path>
|
||||
.. genex:: $<PATH:NORMAL_PATH,path...>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
Returns ``path`` normalized according to the steps described in
|
||||
:ref:`Normalization`.
|
||||
|
||||
.. genex:: $<PATH:RELATIVE_PATH,path,base_directory>
|
||||
.. genex:: $<PATH:RELATIVE_PATH,path...,base_directory>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
@@ -547,7 +556,7 @@ in cmake-style format.
|
||||
See :ref:`cmake_path(RELATIVE_PATH) <cmake_path-RELATIVE_PATH>` for more
|
||||
details.
|
||||
|
||||
.. genex:: $<PATH:ABSOLUTE_PATH[,NORMALIZE],path,base_directory>
|
||||
.. genex:: $<PATH:ABSOLUTE_PATH[,NORMALIZE],path...,base_directory>
|
||||
|
||||
.. versionadded:: 3.24
|
||||
|
||||
|
||||
5
Help/release/dev/PATH-genex-support-list.rst
Normal file
5
Help/release/dev/PATH-genex-support-list.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
PATH-genex-supports-list
|
||||
------------------------
|
||||
|
||||
* The :genex:`$<PATH>` generator expression learned to process list of paths
|
||||
for decomposition and transformation operations.
|
||||
@@ -688,6 +688,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
const GeneratorExpressionContent* content,
|
||||
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
|
||||
{
|
||||
static auto processList =
|
||||
[](std::string const& arg,
|
||||
std::function<void(std::string&)> transform) -> std::string {
|
||||
auto list = cmExpandedList(arg);
|
||||
std::for_each(list.begin(), list.end(), std::move(transform));
|
||||
return cmJoin(list, ";");
|
||||
};
|
||||
|
||||
static std::unordered_map<
|
||||
cm::string_view,
|
||||
std::function<std::string(cmGeneratorExpressionContext*,
|
||||
@@ -698,38 +706,49 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "GET_ROOT_NAME"_s, args) &&
|
||||
!args.front().empty()
|
||||
? cmCMakePath{ args.front() }.GetRootName().String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "GET_ROOT_NAME"_s, args) &&
|
||||
!args.front().empty()) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetRootName().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "GET_ROOT_DIRECTORY"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "GET_ROOT_DIRECTORY"_s,
|
||||
args) &&
|
||||
!args.front().empty()
|
||||
? cmCMakePath{ args.front() }.GetRootDirectory().String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "GET_ROOT_DIRECTORY"_s, args) &&
|
||||
!args.front().empty()) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetRootDirectory().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "GET_ROOT_PATH"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "GET_ROOT_PATH"_s, args) &&
|
||||
!args.front().empty()
|
||||
? cmCMakePath{ args.front() }.GetRootPath().String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "GET_ROOT_PATH"_s, args) &&
|
||||
!args.front().empty()) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetRootPath().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "GET_FILENAME"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "GET_FILENAME"_s, args) &&
|
||||
!args.front().empty()
|
||||
? cmCMakePath{ args.front() }.GetFileName().String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "GET_FILENAME"_s, args) &&
|
||||
!args.front().empty()) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetFileName().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "GET_EXTENSION"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
@@ -746,9 +765,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
if (args.front().empty()) {
|
||||
return std::string{};
|
||||
}
|
||||
return lastOnly
|
||||
? cmCMakePath{ args.front() }.GetExtension().String()
|
||||
: cmCMakePath{ args.front() }.GetWideExtension().String();
|
||||
if (lastOnly) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetExtension().String();
|
||||
});
|
||||
}
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetWideExtension().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
@@ -766,9 +790,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
if (args.front().empty()) {
|
||||
return std::string{};
|
||||
}
|
||||
return lastOnly
|
||||
? cmCMakePath{ args.front() }.GetStem().String()
|
||||
: cmCMakePath{ args.front() }.GetNarrowStem().String();
|
||||
if (lastOnly) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetStem().String();
|
||||
});
|
||||
}
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetNarrowStem().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
@@ -776,19 +805,24 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "GET_RELATIVE_PART"_s,
|
||||
args) &&
|
||||
!args.front().empty()
|
||||
? cmCMakePath{ args.front() }.GetRelativePath().String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "GET_RELATIVE_PART"_s, args) &&
|
||||
!args.front().empty()) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetRelativePath().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "GET_PARENT_PATH"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "GET_PARENT_PATH"_s, args)
|
||||
? cmCMakePath{ args.front() }.GetParentPath().String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "GET_PARENT_PATH"_s, args)) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.GetParentPath().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "HAS_ROOT_NAME"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
@@ -904,10 +938,12 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
normalize ? "CMAKE_PATH,NORMALIZE"_s
|
||||
: "CMAKE_PATH"_s,
|
||||
args.size(), 1)) {
|
||||
auto path =
|
||||
cmCMakePath{ args.front(), cmCMakePath::auto_format };
|
||||
return normalize ? path.Normal().GenericString()
|
||||
: path.GenericString();
|
||||
return processList(
|
||||
args.front(), [normalize](std::string& value) {
|
||||
auto path = cmCMakePath{ value, cmCMakePath::auto_format };
|
||||
value = normalize ? path.Normal().GenericString()
|
||||
: path.GenericString();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
@@ -917,11 +953,16 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
Arguments& args) -> std::string {
|
||||
if (CheckPathParametersEx(ctx, cnt, "APPEND"_s, args.size(), 1,
|
||||
false)) {
|
||||
cmCMakePath path;
|
||||
for (const auto& p : args) {
|
||||
path /= p;
|
||||
}
|
||||
return path.String();
|
||||
auto const& list = args.front();
|
||||
args.advance(1);
|
||||
|
||||
return processList(list, [&args](std::string& value) {
|
||||
cmCMakePath path{ value };
|
||||
for (const auto& p : args) {
|
||||
path /= p;
|
||||
}
|
||||
value = path.String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
@@ -929,20 +970,26 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "REMOVE_FILENAME"_s, args) &&
|
||||
!args.front().empty()
|
||||
? cmCMakePath{ args.front() }.RemoveFileName().String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "REMOVE_FILENAME"_s, args) &&
|
||||
!args.front().empty()) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.RemoveFileName().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "REPLACE_FILENAME"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "REPLACE_FILENAME"_s, args, 2)
|
||||
? cmCMakePath{ args[0] }
|
||||
.ReplaceFileName(cmCMakePath{ args[1] })
|
||||
.String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "REPLACE_FILENAME"_s, args, 2)) {
|
||||
return processList(args.front(), [&args](std::string& value) {
|
||||
value = cmCMakePath{ value }
|
||||
.ReplaceFileName(cmCMakePath{ args[1] })
|
||||
.String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "REMOVE_EXTENSION"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
@@ -959,9 +1006,14 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
if (args.front().empty()) {
|
||||
return std::string{};
|
||||
}
|
||||
return lastOnly
|
||||
? cmCMakePath{ args.front() }.RemoveExtension().String()
|
||||
: cmCMakePath{ args.front() }.RemoveWideExtension().String();
|
||||
if (lastOnly) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.RemoveExtension().String();
|
||||
});
|
||||
}
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.RemoveWideExtension().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
@@ -979,13 +1031,17 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
: "REPLACE_EXTENSION"_s,
|
||||
args.size(), 2)) {
|
||||
if (lastOnly) {
|
||||
return cmCMakePath{ args[0] }
|
||||
.ReplaceExtension(cmCMakePath{ args[1] })
|
||||
.String();
|
||||
return processList(args.front(), [&args](std::string& value) {
|
||||
value = cmCMakePath{ value }
|
||||
.ReplaceExtension(cmCMakePath{ args[1] })
|
||||
.String();
|
||||
});
|
||||
}
|
||||
return cmCMakePath{ args[0] }
|
||||
.ReplaceWideExtension(cmCMakePath{ args[1] })
|
||||
.String();
|
||||
return processList(args.front(), [&args](std::string& value) {
|
||||
value = cmCMakePath{ value }
|
||||
.ReplaceWideExtension(cmCMakePath{ args[1] })
|
||||
.String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
@@ -993,18 +1049,24 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "NORMAL_PATH"_s, args) &&
|
||||
!args.front().empty()
|
||||
? cmCMakePath{ args.front() }.Normal().String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "NORMAL_PATH"_s, args) &&
|
||||
!args.front().empty()) {
|
||||
return processList(args.front(), [](std::string& value) {
|
||||
value = cmCMakePath{ value }.Normal().String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "RELATIVE_PATH"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
const GeneratorExpressionContent* cnt,
|
||||
Arguments& args) -> std::string {
|
||||
return CheckPathParameters(ctx, cnt, "RELATIVE_PATH"_s, args, 2)
|
||||
? cmCMakePath{ args[0] }.Relative(args[1]).String()
|
||||
: std::string{};
|
||||
if (CheckPathParameters(ctx, cnt, "RELATIVE_PATH"_s, args, 2)) {
|
||||
return processList(args.front(), [&args](std::string& value) {
|
||||
value = cmCMakePath{ value }.Relative(args[1]).String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} },
|
||||
{ "ABSOLUTE_PATH"_s,
|
||||
[](cmGeneratorExpressionContext* ctx,
|
||||
@@ -1018,8 +1080,11 @@ static const struct PathNode : public cmGeneratorExpressionNode
|
||||
normalize ? "ABSOLUTE_PATH,NORMALIZE"_s
|
||||
: "ABSOLUTE_PATH"_s,
|
||||
args.size(), 2)) {
|
||||
auto path = cmCMakePath{ args[0] }.Absolute(args[1]);
|
||||
return normalize ? path.Normal().String() : path.String();
|
||||
return processList(
|
||||
args.front(), [&args, normalize](std::string& value) {
|
||||
auto path = cmCMakePath{ value }.Absolute(args[1]);
|
||||
value = normalize ? path.Normal().String() : path.String();
|
||||
});
|
||||
}
|
||||
return std::string{};
|
||||
} }
|
||||
|
||||
@@ -31,4 +31,28 @@ if (NOT output STREQUAL reference)
|
||||
endif()
|
||||
|
||||
|
||||
######################################
|
||||
## tests with list of paths
|
||||
######################################
|
||||
unset (reference)
|
||||
foreach(item IN ITEMS "../../a/d" "/a/d/../e")
|
||||
cmake_path(ABSOLUTE_PATH item BASE_DIRECTORY "/x/y/a/f")
|
||||
list(APPEND reference "${item}")
|
||||
endforeach()
|
||||
set(output "$<PATH:ABSOLUTE_PATH,../../a/d;/a/d/../e,/x/y/a/f>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
unset (reference)
|
||||
foreach(item IN ITEMS "../../a/d" "/a/d/../e")
|
||||
cmake_path(ABSOLUTE_PATH item BASE_DIRECTORY "/x/y/a/f" NORMALIZE)
|
||||
list(APPEND reference "${item}")
|
||||
endforeach()
|
||||
set(output "$<PATH:ABSOLUTE_PATH,NORMALIZE,../../a/d;/a/d/../e,/x/y/a/f>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
|
||||
check_errors("PATH:ABSOLUTE_PATH" ${errors})
|
||||
|
||||
@@ -65,4 +65,39 @@ if (WIN32)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
######################################
|
||||
## tests with list of paths
|
||||
######################################
|
||||
unset(reference)
|
||||
foreach(item IN ITEMS "/a/b" "/x/y")
|
||||
cmake_path (APPEND result "${item}" "c")
|
||||
list(APPEND reference "${result}")
|
||||
endforeach()
|
||||
set(output "$<PATH:APPEND,/a/b;/x/y,c>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
unset(reference)
|
||||
foreach(item IN ITEMS "a" "c")
|
||||
cmake_path (APPEND item "")
|
||||
list(APPEND reference "${item}")
|
||||
endforeach()
|
||||
set(output "$<PATH:APPEND,a;c,>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
unset(reference)
|
||||
foreach(item IN ITEMS "a/" "c/")
|
||||
cmake_path (APPEND item "/b")
|
||||
list(APPEND reference "${item}")
|
||||
endforeach()
|
||||
set(output "$<PATH:APPEND,a/;c/,/b>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
|
||||
check_errors ("PATH:APPEND" ${errors})
|
||||
|
||||
@@ -50,4 +50,46 @@ if (WIN32)
|
||||
endif()
|
||||
|
||||
|
||||
######################################
|
||||
## tests with list of paths
|
||||
######################################
|
||||
set(reference "/x/y/z/../../a/d;/x/y/z/../../b/e")
|
||||
set(output "$<PATH:CMAKE_PATH,/x/y/z/../../a/d;/x/y/z/../../b/e>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
unset(reference)
|
||||
foreach(path IN ITEMS "/x/y/z/../../a/d" "/x/y/z/../../b/e")
|
||||
cmake_path(SET result NORMALIZE "${path}")
|
||||
list(APPEND reference "${result}")
|
||||
endforeach()
|
||||
set(output "$<PATH:CMAKE_PATH,NORMALIZE,/x/y/z/../../a/d;/x/y/z/../../b/e>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
unset(reference)
|
||||
foreach(path IN ITEMS "/x\\y/z\\..\\../a/d" "/x\\y/z\\..\\../b/e")
|
||||
cmake_path(SET result "${path}")
|
||||
list(APPEND reference "${result}")
|
||||
endforeach()
|
||||
set(output "$<PATH:CMAKE_PATH,/x\y/z\..\../a/d;/x\y/z\..\../b/e>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
unset(reference)
|
||||
foreach(path IN ITEMS "/x\\y/z\\..\\../a/d" "/x\\y/z\\..\\../b/e")
|
||||
cmake_path(SET result NORMALIZE "${path}")
|
||||
list(APPEND reference "${result}")
|
||||
endforeach()
|
||||
set(output "$<PATH:CMAKE_PATH,NORMALIZE,/x\y/z\..\../a/d;/x\y/z\..\../b/e>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
check_errors("PATH:CMAKE_PATH" ${errors})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 3.18...3.24)
|
||||
cmake_minimum_required(VERSION 3.18...3.25)
|
||||
|
||||
project(${RunCMake_TEST} NONE)
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
cmake_policy(SET CMP0140 NEW)
|
||||
|
||||
include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
|
||||
unset (errors)
|
||||
@@ -308,4 +309,126 @@ if (NOT output STREQUAL reference)
|
||||
endif()
|
||||
|
||||
|
||||
######################################
|
||||
## third, tests with list of paths
|
||||
######################################
|
||||
if (WIN32)
|
||||
set (paths "C:/aa/bb/cc.ext1.ext2" "D:/xx/yy/zz.ext3.ext4")
|
||||
else()
|
||||
set (paths "/aa/bb/cc.ext1.ext2" "/xx/yy/zz.ext3.ext4")
|
||||
endif()
|
||||
|
||||
function (compute_reference action)
|
||||
unset(reference)
|
||||
foreach (path IN LISTS paths)
|
||||
cmake_path(GET path ${ARGV} result)
|
||||
list(APPEND reference "${result}")
|
||||
endforeach()
|
||||
if (reference STREQUAL "")
|
||||
# define the list as 2 empty elements
|
||||
set(reference ";")
|
||||
endif()
|
||||
|
||||
return(PROPAGATE reference)
|
||||
endfunction()
|
||||
|
||||
compute_reference(ROOT_NAME)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_ROOT_NAME,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_ROOT_NAME,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "ROOT_NAME returns bad data: ${output}")
|
||||
endif()
|
||||
|
||||
compute_reference(ROOT_DIRECTORY)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_ROOT_DIRECTORY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_ROOT_DIRECTORY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "ROOT_DIRECTORY returns bad data: ${output}")
|
||||
endif()
|
||||
|
||||
compute_reference(ROOT_PATH)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_ROOT_PATH,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_ROOT_PATH,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "ROOT_PATH returns bad data: ${output}")
|
||||
endif()
|
||||
|
||||
compute_reference(FILENAME)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_FILENAME,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_FILENAME,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "FILENAME returns bad data: ${output}")
|
||||
endif()
|
||||
|
||||
compute_reference(EXTENSION)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_EXTENSION,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_EXTENSION,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "EXTENSION returns bad data: ${output}")
|
||||
endif()
|
||||
compute_reference(EXTENSION LAST_ONLY)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_EXTENSION,LAST_ONLY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_EXTENSION,LAST_ONLY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "EXTENSION LAST_ONLY returns bad data: ${output}")
|
||||
endif()
|
||||
|
||||
compute_reference(STEM)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_STEM,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_STEM,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "STEM returns bad data: ${output}")
|
||||
endif()
|
||||
compute_reference(STEM LAST_ONLY)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_STEM,LAST_ONLY,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_STEM,LAST_ONLY,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "STEM LAST_ONLY returns bad data: ${reference}")
|
||||
endif()
|
||||
|
||||
compute_reference(RELATIVE_PART)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_RELATIVE_PART,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_RELATIVE_PART,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "RELATIVE_PART returns bad data: ${output}")
|
||||
endif()
|
||||
|
||||
compute_reference(PARENT_PATH)
|
||||
if (WIN32)
|
||||
set(output "$<PATH:GET_PARENT_PATH,C:/aa/bb/cc.ext1.ext2;D:/xx/yy/zz.ext3.ext4>")
|
||||
else()
|
||||
set (output "$<PATH:GET_PARENT_PATH,/aa/bb/cc.ext1.ext2;/xx/yy/zz.ext3.ext4>")
|
||||
endif()
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "PARENT_PATH returns bad data: ${output}")
|
||||
endif()
|
||||
|
||||
|
||||
check_errors("PATH:GET..." ${errors})
|
||||
|
||||
@@ -40,4 +40,18 @@ if (WIN32)
|
||||
endif()
|
||||
|
||||
|
||||
######################################
|
||||
## tests with list of paths
|
||||
######################################
|
||||
unset (reference)
|
||||
foreach(item IN ITEMS "a/./b/.." "x/.//y/z//..")
|
||||
cmake_path(NORMAL_PATH item)
|
||||
list(APPEND reference "${item}")
|
||||
endforeach()
|
||||
set(output "$<PATH:NORMAL_PATH,a/./b/..;x/.//y/z//..>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
|
||||
check_errors("PATH:NORMAL_PATH" ${errors})
|
||||
|
||||
@@ -61,4 +61,18 @@ if (WIN32)
|
||||
endif()
|
||||
|
||||
|
||||
######################################
|
||||
## tests with list of paths
|
||||
######################################
|
||||
unset (reference)
|
||||
foreach(item IN ITEMS "/a//d" "/a/b/e")
|
||||
cmake_path(RELATIVE_PATH item BASE_DIRECTORY "/a/b/c")
|
||||
list(APPEND reference "${item}")
|
||||
endforeach()
|
||||
set(output "$<PATH:RELATIVE_PATH,/a//d;/a/b/e,/a/b/c>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "'${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
|
||||
check_errors("PATH:RELATIVE_PATH" ${errors})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
cmake_policy(SET CMP0140 NEW)
|
||||
|
||||
include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
|
||||
unset (errors)
|
||||
@@ -62,4 +63,39 @@ if (NOT output STREQUAL reference)
|
||||
endif()
|
||||
|
||||
|
||||
######################################
|
||||
## tests with list of paths
|
||||
######################################
|
||||
function (compute_reference action)
|
||||
unset(reference)
|
||||
foreach (path IN LISTS paths)
|
||||
cmake_path(${action} path ${ARGN})
|
||||
list(APPEND reference "${path}")
|
||||
endforeach()
|
||||
|
||||
return(PROPAGATE reference)
|
||||
endfunction()
|
||||
|
||||
set (paths "a/b/c.e.f" "g/h/i.j.k")
|
||||
compute_reference(REMOVE_FILENAME)
|
||||
set(output "$<PATH:REMOVE_FILENAME,a/b/c.e.f;g/h/i.j.k>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "FILENAME: '${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
set (paths "a/b/c.e.f" "g/h/i.j.k")
|
||||
compute_reference(REMOVE_EXTENSION)
|
||||
set(output "$<PATH:REMOVE_EXTENSION,a/b/c.e.f;g/h/i.j.k>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
set (reference "a/b/c.e.f" "g/h/i.j.k")
|
||||
compute_reference(REMOVE_EXTENSION LAST_ONLY)
|
||||
set(output "$<PATH:REMOVE_EXTENSION,LAST_ONLY,a/b/c.e.f;g/h/i.j.k>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
|
||||
check_errors("PATH:REMOVE..." ${errors})
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
cmake_policy(SET CMP0140 NEW)
|
||||
|
||||
include ("${RunCMake_SOURCE_DIR}/check_errors.cmake")
|
||||
unset (errors)
|
||||
@@ -70,4 +71,39 @@ if (NOT output STREQUAL reference)
|
||||
endif()
|
||||
|
||||
|
||||
######################################
|
||||
## tests with list of paths
|
||||
######################################
|
||||
function (compute_reference action new_value)
|
||||
unset(reference)
|
||||
foreach (path IN LISTS paths)
|
||||
cmake_path(${action} path "${new_value}" ${ARGN})
|
||||
list(APPEND reference "${path}")
|
||||
endforeach()
|
||||
|
||||
return(PROPAGATE reference)
|
||||
endfunction()
|
||||
|
||||
set (paths "a/b/c.e.f" "g/h/i.j.k")
|
||||
compute_reference(REPLACE_FILENAME "x.y")
|
||||
set(output "$<PATH:REPLACE_FILENAME,a/b/c.e.f;g/h/i.j.k,x.y>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "FILENAME: '${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
set (paths "a/b/c.e.f" "g/h/i.j.k")
|
||||
compute_reference(REPLACE_EXTENSION ".x")
|
||||
set(output "$<PATH:REPLACE_EXTENSION,a/b/c.e.f;g/h/i.j.k,.x>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
set (paths "a/b/c.e.f" "g/h/i.j.k")
|
||||
compute_reference(REPLACE_EXTENSION ".x" LAST_ONLY)
|
||||
set(output "$<PATH:REPLACE_EXTENSION,LAST_ONLY,a/b/c.e.f;g/h/i.j.k,.x>")
|
||||
if (NOT output STREQUAL reference)
|
||||
list (APPEND errors "EXTENSION: '${output}' instead of '${reference}'")
|
||||
endif()
|
||||
|
||||
|
||||
check_errors("PATH:REPLACE..." ${errors})
|
||||
|
||||
Reference in New Issue
Block a user