Merge topic 'genex-SHELL_PATH'

ca6ba3fe Genex: Add a SHELL_PATH expression
7de868c4 Tests: Simplify GeneratorExpression check implementation
This commit is contained in:
Brad King 2015-09-28 10:44:43 -04:00 committed by CMake Topic Stage
commit cfcd5e8518
13 changed files with 123 additions and 21 deletions

View File

@ -278,3 +278,7 @@ Available output expressions are:
object of type ``OBJECT_LIBRARY``. This expression may only be used in object of type ``OBJECT_LIBRARY``. This expression may only be used in
the sources of :command:`add_library` and :command:`add_executable` the sources of :command:`add_library` and :command:`add_executable`
commands. commands.
``$<SHELL_PATH:...>``
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.

View File

@ -0,0 +1,6 @@
genex-SHELL_PATH
----------------
* A new ``$<SHELL_PATH:...>``
:manual:`generator expression <cmake-generator-expressions(7)>`
has been added.

View File

@ -13,6 +13,7 @@
#include "cmGeneratorExpressionNode.h" #include "cmGeneratorExpressionNode.h"
#include "cmGlobalGenerator.h" #include "cmGlobalGenerator.h"
#include "cmAlgorithms.h" #include "cmAlgorithms.h"
#include "cmOutputConverter.h"
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
std::string cmGeneratorExpressionNode::EvaluateDependentExpression( std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
@ -1791,6 +1792,27 @@ TargetFilesystemArtifactNodeGroup<ArtifactSonameTag> targetSoNameNodeGroup;
static const static const
TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup; TargetFilesystemArtifactNodeGroup<ArtifactPdbTag> targetPdbNodeGroup;
//----------------------------------------------------------------------------
static const struct ShellPathNode : public cmGeneratorExpressionNode
{
ShellPathNode() {}
std::string Evaluate(const std::vector<std::string> &parameters,
cmGeneratorExpressionContext *context,
const GeneratorExpressionContent *content,
cmGeneratorExpressionDAGChecker *) const
{
if (!cmSystemTools::FileIsFullPath(parameters.front()))
{
reportError(context, content->GetOriginalExpression(),
"\"" + parameters.front() + "\" is not an absolute path.");
return std::string();
}
cmOutputConverter converter(context->Makefile->GetStateSnapshot());
return converter.ConvertDirectorySeparatorsForShell(parameters.front());
}
} shellPathNode;
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const cmGeneratorExpressionNode* const cmGeneratorExpressionNode*
cmGeneratorExpressionNode::GetNode(const std::string &identifier) cmGeneratorExpressionNode::GetNode(const std::string &identifier)
@ -1846,6 +1868,7 @@ cmGeneratorExpressionNode::GetNode(const std::string &identifier)
nodeMap["JOIN"] = &joinNode; nodeMap["JOIN"] = &joinNode;
nodeMap["LINK_ONLY"] = &linkOnlyNode; nodeMap["LINK_ONLY"] = &linkOnlyNode;
nodeMap["COMPILE_LANGUAGE"] = &languageNode; nodeMap["COMPILE_LANGUAGE"] = &languageNode;
nodeMap["SHELL_PATH"] = &shellPathNode;
} }
NodeMap::const_iterator i = nodeMap.find(identifier); NodeMap::const_iterator i = nodeMap.find(identifier);
if (i == nodeMap.end()) if (i == nodeMap.end())

View File

@ -142,6 +142,21 @@ std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
} }
else if(output == SHELL || output == WATCOMQUOTE) else if(output == SHELL || output == WATCOMQUOTE)
{ {
result = this->ConvertDirectorySeparatorsForShell(source);
result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
}
else if(output == RESPONSE)
{
result = this->EscapeForShell(result, false, false, false);
}
return result;
}
//----------------------------------------------------------------------------
std::string cmOutputConverter::ConvertDirectorySeparatorsForShell(
const std::string& source) const
{
std::string result = source;
// For the MSYS shell convert drive letters to posix paths, so // For the MSYS shell convert drive letters to posix paths, so
// that c:/some/path becomes /c/some/path. This is needed to // that c:/some/path becomes /c/some/path. This is needed to
// avoid problems with the shell path translation. // avoid problems with the shell path translation.
@ -157,12 +172,6 @@ std::string cmOutputConverter::ConvertToOutputFormat(const std::string& source,
{ {
std::replace(result.begin(), result.end(), '/', '\\'); std::replace(result.begin(), result.end(), '/', '\\');
} }
result = this->EscapeForShell(result, true, false, output == WATCOMQUOTE);
}
else if(output == RESPONSE)
{
result = this->EscapeForShell(result, false, false, false);
}
return result; return result;
} }

View File

@ -45,6 +45,8 @@ public:
std::string Convert(RelativeRoot remote, const std::string& local, std::string Convert(RelativeRoot remote, const std::string& local,
OutputFormat output = UNCHANGED, OutputFormat output = UNCHANGED,
bool optional = false) const; bool optional = false) const;
std::string ConvertDirectorySeparatorsForShell(
const std::string& source) const;
/** /**
* Get path for the specified relative root. * Get path for the specified relative root.

View File

@ -66,7 +66,7 @@ add_custom_target(check-part1 ALL
-Dtest_colons_4=$<1:C:\\CMake> -Dtest_colons_4=$<1:C:\\CMake>
-Dtest_colons_5=$<1:C:/CMake> -Dtest_colons_5=$<1:C:/CMake>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part1.cmake -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part1.cmake
COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 3)" COMMAND ${CMAKE_COMMAND} -E echo "check done (part 1 of 4)"
VERBATIM VERBATIM
) )
@ -137,7 +137,7 @@ add_custom_target(check-part2 ALL
-Dtest_arbitrary_content_comma_9=$<1:a,,b,,> -Dtest_arbitrary_content_comma_9=$<1:a,,b,,>
-Dtest_arbitrary_content_comma_10=$<1:,,a,,b,,> -Dtest_arbitrary_content_comma_10=$<1:,,a,,b,,>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part2.cmake
COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 3)" COMMAND ${CMAKE_COMMAND} -E echo "check done (part 2 of 4)"
VERBATIM VERBATIM
) )
@ -221,7 +221,27 @@ add_custom_target(check-part3 ALL
-Dequal22=$<EQUAL:10,-012> -Dequal22=$<EQUAL:10,-012>
-Dequal23=$<EQUAL:-10,-012> -Dequal23=$<EQUAL:-10,-012>
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake -P ${CMAKE_CURRENT_SOURCE_DIR}/check-part3.cmake
COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 3)" COMMAND ${CMAKE_COMMAND} -E echo "check done (part 3 of 4)"
VERBATIM
)
if(WIN32)
set(test_shell_path c:/shell/path)
else()
set(test_shell_path /shell/path)
endif()
set(path_prefix BYPASS_FURTHER_CONVERSION)
add_custom_target(check-part4 ALL
COMMAND ${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}
-DWIN32=${WIN32}
-DCMAKE_GENERATOR=${CMAKE_GENERATOR}
-P ${CMAKE_CURRENT_SOURCE_DIR}/check-part4.cmake
COMMAND ${CMAKE_COMMAND} -E echo "check done (part 4 of 4)"
VERBATIM VERBATIM
) )

View File

@ -1,5 +1,5 @@
macro(check var val) function(check var val)
if(NOT "${${var}}" STREQUAL "${val}") if(NOT "${${var}}" STREQUAL "${val}")
message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"") message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"")
endif() endif()
endmacro() endfunction()

View File

@ -55,5 +55,5 @@ check(test_semicolon ";")
check(test_colons_1 ":") check(test_colons_1 ":")
check(test_colons_2 "::") check(test_colons_2 "::")
check(test_colons_3 "Qt5::Core") check(test_colons_3 "Qt5::Core")
check(test_colons_4 "C:\\\\CMake") check(test_colons_4 [[C:\CMake]])
check(test_colons_5 "C:/CMake") check(test_colons_5 "C:/CMake")

View File

@ -0,0 +1,15 @@
include(${CMAKE_CURRENT_LIST_DIR}/check-common.cmake)
string(REPLACE ${path_prefix} "" test_shell_path ${test_shell_path})
if(WIN32)
if(CMAKE_GENERATOR STREQUAL "MSYS Makefiles")
check(test_shell_path [[/c/shell/path]])
elseif(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
check(test_shell_path [[c:/shell/path]])
else()
check(test_shell_path [[c:\shell\path]])
endif()
else()
check(test_shell_path [[/shell/path]])
endif()

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,17 @@
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\)
+
CMake Error at BadSHELL_PATH.cmake:[0-9]+ \(add_custom_target\):
Error evaluating generator expression:
\$<SHELL_PATH:Relative/Path>
"Relative/Path" is not an absolute path.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,4 @@
add_custom_target(check ALL COMMAND check
$<SHELL_PATH:>
$<SHELL_PATH:Relative/Path>
VERBATIM)

View File

@ -10,6 +10,7 @@ run_cmake(BadTargetName)
run_cmake(BadTargetTypeInterface) run_cmake(BadTargetTypeInterface)
run_cmake(BadTargetTypeObject) run_cmake(BadTargetTypeObject)
run_cmake(BadInstallPrefix) run_cmake(BadInstallPrefix)
run_cmake(BadSHELL_PATH)
run_cmake(CMP0044-WARN) run_cmake(CMP0044-WARN)
run_cmake(NonValidTarget-C_COMPILER_ID) run_cmake(NonValidTarget-C_COMPILER_ID)
run_cmake(NonValidTarget-CXX_COMPILER_ID) run_cmake(NonValidTarget-CXX_COMPILER_ID)