mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-03 20:29:56 -06:00
Merge topic 'shell_path'
463c2fba4eGenex: Teach SHELL_PATH to support a list of paths21da25d2a8Tests: Generalize GeneratorExpression MSYS path conversion workaround Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !3057
This commit is contained in:
@@ -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.
|
||||
|
||||
Debugging
|
||||
=========
|
||||
|
||||
5
Help/release/dev/shell_path.rst
Normal file
5
Help/release/dev/shell_path.rst
Normal file
@@ -0,0 +1,5 @@
|
||||
shell_path
|
||||
----------
|
||||
|
||||
* 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;
|
||||
listOut.reserve(listIn.size());
|
||||
for (auto const& in : listIn) {
|
||||
if (!cmSystemTools::FileIsFullPath(in)) {
|
||||
reportError(context, content->GetOriginalExpression(),
|
||||
"\"" + in + "\" is not an absolute path.");
|
||||
return std::string();
|
||||
}
|
||||
listOut.emplace_back(converter.ConvertDirectorySeparatorsForShell(in));
|
||||
}
|
||||
return cmJoin(listOut, separator);
|
||||
}
|
||||
} shellPathNode;
|
||||
|
||||
|
||||
@@ -3,11 +3,26 @@ project(GeneratorExpression)
|
||||
|
||||
include(CTest)
|
||||
|
||||
# Real projects normally want the MSYS shell path conversion, but for this test
|
||||
# we need to verify that the command line is constructed with the proper string.
|
||||
set(msys1_prefix "")
|
||||
set(msys2_no_conv "")
|
||||
if(CMAKE_GENERATOR STREQUAL "MSYS Makefiles")
|
||||
execute_process(COMMAND "uname" OUTPUT_VARIABLE uname)
|
||||
if("${uname}" MATCHES "^MINGW32")
|
||||
# MinGW.org MSYS 1.0 does not support generic path conversion suppression
|
||||
set(msys1_prefix MSYS1_PREFIX)
|
||||
else()
|
||||
# msys2 supports generic path conversion suppression
|
||||
set(msys2_no_conv env MSYS2_ARG_CONV_EXCL=-D)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# This test is split into multiple parts as needed to avoid NMake command
|
||||
# length limits.
|
||||
|
||||
add_custom_target(check-part1 ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
COMMAND ${msys2_no_conv} ${CMAKE_COMMAND}
|
||||
-Dtest_0=$<0:nothing>
|
||||
-Dtest_0_with_comma=$<0:-Wl,--no-undefined>
|
||||
-Dtest_1=$<1:content>
|
||||
@@ -97,7 +112,7 @@ add_library(empty5 empty.cpp)
|
||||
target_include_directories(empty5 PRIVATE /empty5/private1 /empty5/private2)
|
||||
|
||||
add_custom_target(check-part2 ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
COMMAND ${msys2_no_conv} ${CMAKE_COMMAND}
|
||||
-Dtest_incomplete_1=$<
|
||||
-Dtest_incomplete_2=$<something
|
||||
-Dtest_incomplete_3=$<something:
|
||||
@@ -188,7 +203,7 @@ set_property(TARGET importedFallback PROPERTY MAP_IMPORTED_CONFIG_DEBUG "" DEBUG
|
||||
set_property(TARGET importedFallback PROPERTY MAP_IMPORTED_CONFIG_RELEASE "")
|
||||
|
||||
add_custom_target(check-part3 ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
COMMAND ${msys2_no_conv} ${CMAKE_COMMAND}
|
||||
-Dtest_version_greater_1=$<VERSION_GREATER:1.0,1.1.1>
|
||||
-Dtest_version_greater_2=$<VERSION_GREATER:1.1.1,1.0>
|
||||
-Dtest_version_less_1=$<VERSION_LESS:1.1.1,1.0>
|
||||
@@ -241,17 +256,19 @@ add_custom_target(check-part3 ALL
|
||||
|
||||
if(WIN32)
|
||||
set(test_shell_path c:/shell/path)
|
||||
set(test_shell_path2 c:/shell/path d:/another/path)
|
||||
else()
|
||||
set(test_shell_path /shell/path)
|
||||
set(test_shell_path2 /shell/path /another/path)
|
||||
endif()
|
||||
set(path_prefix BYPASS_FURTHER_CONVERSION)
|
||||
|
||||
add_custom_target(check-part4 ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
COMMAND ${msys2_no_conv} ${CMAKE_COMMAND}
|
||||
# Prefix path to bypass its further conversion when being processed by
|
||||
# CMake as command-line argument
|
||||
-Dtest_shell_path=${path_prefix}$<SHELL_PATH:${test_shell_path}>
|
||||
-Dpath_prefix=${path_prefix}
|
||||
-Dmsys1_prefix=${msys1_prefix}
|
||||
-Dtest_shell_path=${msys1_prefix}$<SHELL_PATH:${test_shell_path}>
|
||||
"-Dtest_shell_path2=$<SHELL_PATH:${test_shell_path2}>"
|
||||
-Dif_1=$<IF:1,a,b>
|
||||
-Dif_2=$<IF:0,a,b>
|
||||
-Dif_3=$<IF:$<EQUAL:10,30>,a,b>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
|
||||
|
||||
string(REPLACE ${path_prefix} "" test_shell_path ${test_shell_path})
|
||||
if(msys1_prefix)
|
||||
string(REPLACE "${msys1_prefix}" "" test_shell_path ${test_shell_path})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(CMAKE_GENERATOR STREQUAL "MSYS Makefiles")
|
||||
@@ -13,6 +15,17 @@ if(WIN32)
|
||||
else()
|
||||
check(test_shell_path [[/shell/path]])
|
||||
endif()
|
||||
if(WIN32)
|
||||
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]])
|
||||
else()
|
||||
check(test_shell_path2 [[c:\shell\path;d:\another\path]])
|
||||
endif()
|
||||
else()
|
||||
check(test_shell_path2 [[/shell/path:/another/path]])
|
||||
endif()
|
||||
|
||||
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:
|
||||
|
||||
\$<SHELL_PATH:;>
|
||||
|
||||
"" is not an absolute path.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
add_custom_target(check ALL COMMAND check
|
||||
$<SHELL_PATH:>
|
||||
$<SHELL_PATH:Relative/Path>
|
||||
"$<SHELL_PATH:;>"
|
||||
VERBATIM)
|
||||
|
||||
Reference in New Issue
Block a user