Commit 463c2fba authored by Henri Manson's avatar Henri Manson Committed by Brad King

Genex: Teach SHELL_PATH to support a list of paths

Extend the genex added by commit ca6ba3fe (Genex: Add a SHELL_PATH
expression, 2015-09-24, v3.4.0-rc1~37^2) to accept a `;`-list of paths,
convert them all, and generate a list separated by the native shell
`PATH``` separator.
parent 21da25d2
......@@ -455,6 +455,11 @@ Output-Related Expressions
Content of ``...`` converted to shell path style. For example, slashes are
converted to backslashes in Windows shells and drive letters are converted
to posix paths in MSYS shells. The ``...`` must be an absolute path.
The ``...`` may be a :ref:`semicolon-separated list <CMake Language Lists>`
of paths, in which case each path is converted individually and a result
list is generated using the shell path separator (``:`` on POSIX and
``;`` on Windows). Be sure to enclose the argument containing this genex
in double quotes in CMake source code so that ``;`` does not split arguments.
* The ``$<SHELL_PATH:...>`` :manual:`generator expression
<cmake-generator-expressions(7)>` gained support for a list of paths.
......@@ -15,6 +15,8 @@
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmState.h"
#include "cmStateSnapshot.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
......@@ -2045,13 +2047,27 @@ static const struct ShellPathNode : public cmGeneratorExpressionNode
const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* /*dagChecker*/) const override
if (!cmSystemTools::FileIsFullPath(parameters.front())) {
std::vector<std::string> listIn;
cmSystemTools::ExpandListArgument(parameters.front(), listIn);
if (listIn.empty()) {
reportError(context, content->GetOriginalExpression(),
"\"" + parameters.front() + "\" is not an absolute path.");
"\"\" is not an absolute path.");
return std::string();
cmOutputConverter converter(context->LG->GetStateSnapshot());
return converter.ConvertDirectorySeparatorsForShell(parameters.front());
cmStateSnapshot snapshot = context->LG->GetStateSnapshot();
cmOutputConverter converter(snapshot);
const char* separator = snapshot.GetState()->UseWindowsShell() ? ";" : ":";
std::vector<std::string> listOut;
for (auto const& in : listIn) {
if (!cmSystemTools::FileIsFullPath(in)) {
reportError(context, content->GetOriginalExpression(),
"\"" + in + "\" is not an absolute path.");
return std::string();
return cmJoin(listOut, separator);
} shellPathNode;
......@@ -256,8 +256,10 @@ add_custom_target(check-part3 ALL
set(test_shell_path c:/shell/path)
set(test_shell_path2 c:/shell/path d:/another/path)
set(test_shell_path /shell/path)
set(test_shell_path2 /shell/path /another/path)
add_custom_target(check-part4 ALL
......@@ -266,6 +268,7 @@ add_custom_target(check-part4 ALL
# CMake as command-line argument
......@@ -15,6 +15,17 @@ if(WIN32)
check(test_shell_path [[/shell/path]])
if(CMAKE_GENERATOR STREQUAL "MSYS Makefiles" AND NOT msys1_prefix)
check(test_shell_path2 [[/c/shell/path:/d/another/path]])
elseif(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
check(test_shell_path2 [[c:/shell/path;d:/another/path]])
check(test_shell_path2 [[c:\shell\path;d:\another\path]])
check(test_shell_path2 [[/shell/path:/another/path]])
check(if_1 "a")
check(if_2 "b")
......@@ -15,3 +15,12 @@ CMake Error at BadSHELL_PATH.cmake:[0-9]+ \(add_custom_target\):
"Relative/Path" is not an absolute path.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at BadSHELL_PATH.cmake:[0-9]+ \(add_custom_target\):
Error evaluating generator expression:
"" is not an absolute path.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
add_custom_target(check ALL COMMAND check
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment