Merge topic 'generator-expression-conditions'
9d9f616
Add $<CONFIG:...> boolean query generator expressionebf05ab
Add boolean generator expressions
This commit is contained in:
commit
3574bb4842
|
@ -16,6 +16,9 @@
|
|||
"Generator expressions are evaluted during build system generation " \
|
||||
"to produce information specific to each build configuration. " \
|
||||
"Valid expressions are:\n" \
|
||||
" $<0:...> = empty string (ignores \"...\")\n" \
|
||||
" $<1:...> = content of \"...\"\n" \
|
||||
" $<CONFIG:cfg> = '1' if config is \"cfg\", else '0'\n" \
|
||||
" $<CONFIGURATION> = configuration name\n" \
|
||||
" $<TARGET_FILE:tgt> = main file (.exe, .so.1.2, .a)\n" \
|
||||
" $<TARGET_LINKER_FILE:tgt> = file used to link (.a, .lib, .so)\n" \
|
||||
|
@ -25,6 +28,12 @@
|
|||
"versions can produce the directory and file name components:\n" \
|
||||
" $<TARGET_FILE_DIR:tgt>/$<TARGET_FILE_NAME:tgt>\n" \
|
||||
" $<TARGET_LINKER_FILE_DIR:tgt>/$<TARGET_LINKER_FILE_NAME:tgt>\n" \
|
||||
" $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n"
|
||||
" $<TARGET_SONAME_FILE_DIR:tgt>/$<TARGET_SONAME_FILE_NAME:tgt>\n" \
|
||||
"Boolean expressions:\n" \
|
||||
" $<AND:?[,?]...> = '1' if all '?' are '1', else '0'\n" \
|
||||
" $<OR:?[,?]...> = '0' if all '?' are '0', else '1'\n" \
|
||||
" $<NOT:?> = '0' if '?' is '1', else '1'\n" \
|
||||
"where '?' is always either '0' or '1'.\n" \
|
||||
""
|
||||
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
#include "cmMakefile.h"
|
||||
#include "cmTarget.h"
|
||||
|
||||
#include <cmsys/String.h>
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
cmGeneratorExpression::cmGeneratorExpression(
|
||||
cmMakefile* mf, const char* config,
|
||||
|
@ -25,6 +27,7 @@ cmGeneratorExpression::cmGeneratorExpression(
|
|||
"_FILE(|_NAME|_DIR):" // Filename component.
|
||||
"([A-Za-z0-9_.-]+)" // Target name.
|
||||
">$");
|
||||
this->TestConfig.compile("^\\$<CONFIG:([A-Za-z0-9_]*)>$");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -102,6 +105,26 @@ bool cmGeneratorExpression::Evaluate()
|
|||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
static bool cmGeneratorExpressionBool(const char* c, std::string& result,
|
||||
const char* name,
|
||||
const char* a, const char* b)
|
||||
{
|
||||
result = a;
|
||||
while((c[0] == '0' || c[0] == '1') && (c[1] == ',' || c[1] == '>'))
|
||||
{
|
||||
if(c[0] == b[0]) { result = b; }
|
||||
c += 2;
|
||||
}
|
||||
if(c[0])
|
||||
{
|
||||
result = name;
|
||||
result += " requires one or more comma-separated '0' or '1' values.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
bool cmGeneratorExpression::Evaluate(const char* expr, std::string& result)
|
||||
{
|
||||
|
@ -116,6 +139,38 @@ bool cmGeneratorExpression::Evaluate(const char* expr, std::string& result)
|
|||
{
|
||||
result = this->Config? this->Config : "";
|
||||
}
|
||||
else if(strncmp(expr, "$<0:",4) == 0)
|
||||
{
|
||||
result = "";
|
||||
}
|
||||
else if(strncmp(expr, "$<1:",4) == 0)
|
||||
{
|
||||
result = std::string(expr+4, strlen(expr)-5);
|
||||
}
|
||||
else if(strncmp(expr, "$<NOT:",6) == 0)
|
||||
{
|
||||
const char* c = expr+6;
|
||||
if((c[0] != '0' && c[0] != '1') || c[1] != '>' || c[2])
|
||||
{
|
||||
result = "NOT requires exactly one '0' or '1' value.";
|
||||
return false;
|
||||
}
|
||||
result = c[0] == '1'? "0" : "1";
|
||||
}
|
||||
else if(strncmp(expr, "$<AND:",6) == 0)
|
||||
{
|
||||
return cmGeneratorExpressionBool(expr+6, result, "AND", "1", "0");
|
||||
}
|
||||
else if(strncmp(expr, "$<OR:",5) == 0)
|
||||
{
|
||||
return cmGeneratorExpressionBool(expr+5, result, "OR", "0", "1");
|
||||
}
|
||||
else if(this->TestConfig.find(expr))
|
||||
{
|
||||
result = cmsysString_strcasecmp(this->TestConfig.match(1).c_str(),
|
||||
this->Config? this->Config:"") == 0
|
||||
? "1":"0";
|
||||
}
|
||||
else
|
||||
{
|
||||
result = "Expression syntax not recognized.";
|
||||
|
|
|
@ -51,6 +51,7 @@ private:
|
|||
std::vector<char> Data;
|
||||
std::stack<size_t> Barriers;
|
||||
cmsys::RegularExpression TargetInfo;
|
||||
cmsys::RegularExpression TestConfig;
|
||||
std::set<cmTarget*> Targets;
|
||||
bool Evaluate();
|
||||
bool Evaluate(const char* expr, std::string& result);
|
||||
|
|
|
@ -551,6 +551,16 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/
|
|||
FAIL_REGULAR_EXPRESSION "Unexpected: ")
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/ArgumentExpansion")
|
||||
|
||||
add_test(GeneratorExpression ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/GeneratorExpression"
|
||||
"${CMake_BINARY_DIR}/Tests/GeneratorExpression"
|
||||
--build-generator ${CMAKE_TEST_GENERATOR}
|
||||
--build-project GeneratorExpression
|
||||
--build-makeprogram ${CMAKE_TEST_MAKEPROGRAM}
|
||||
)
|
||||
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/GeneratorExpression")
|
||||
|
||||
add_test(CustomCommand ${CMAKE_CTEST_COMMAND}
|
||||
--build-and-test
|
||||
"${CMake_SOURCE_DIR}/Tests/CustomCommand"
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
cmake_minimum_required (VERSION 2.8.8)
|
||||
project(GeneratorExpression NONE)
|
||||
|
||||
add_custom_target(check ALL
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-Dtest_0=$<0:nothing>
|
||||
-Dtest_1=$<1:content>
|
||||
-Dconfig=$<CONFIGURATION>
|
||||
-Dtest_and_0=$<AND:0>
|
||||
-Dtest_and_0_0=$<AND:0,0>
|
||||
-Dtest_and_0_1=$<AND:0,1>
|
||||
-Dtest_and_1=$<AND:1>
|
||||
-Dtest_and_1_0=$<AND:1,0>
|
||||
-Dtest_and_1_1=$<AND:1,1>
|
||||
-Dtest_config_0=$<CONFIG:$<CONFIGURATION>x>
|
||||
-Dtest_config_1=$<CONFIG:$<CONFIGURATION>>
|
||||
-Dtest_not_0=$<NOT:0>
|
||||
-Dtest_not_1=$<NOT:1>
|
||||
-Dtest_or_0=$<OR:0>
|
||||
-Dtest_or_0_0=$<OR:0,0>
|
||||
-Dtest_or_0_1=$<OR:0,1>
|
||||
-Dtest_or_1=$<OR:1>
|
||||
-Dtest_or_1_0=$<OR:1,0>
|
||||
-Dtest_or_1_1=$<OR:1,1>
|
||||
-P ${CMAKE_CURRENT_SOURCE_DIR}/check.cmake
|
||||
COMMAND ${CMAKE_COMMAND} -E echo "check done"
|
||||
VERBATIM
|
||||
)
|
|
@ -0,0 +1,25 @@
|
|||
macro(check var val)
|
||||
if(NOT "${${var}}" STREQUAL "${val}")
|
||||
message(SEND_ERROR "${var} is \"${${var}}\", not \"${val}\"")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
message(STATUS "config=[${config}]")
|
||||
check(test_0 "")
|
||||
check(test_1 "content")
|
||||
check(test_and_0 "0")
|
||||
check(test_and_0_0 "0")
|
||||
check(test_and_0_1 "0")
|
||||
check(test_and_1 "1")
|
||||
check(test_and_1_0 "0")
|
||||
check(test_and_1_1 "1")
|
||||
check(test_config_0 "0")
|
||||
check(test_config_1 "1")
|
||||
check(test_not_0 "1")
|
||||
check(test_not_1 "0")
|
||||
check(test_or_0 "0")
|
||||
check(test_or_0_0 "0")
|
||||
check(test_or_0_1 "1")
|
||||
check(test_or_1 "1")
|
||||
check(test_or_1_0 "1")
|
||||
check(test_or_1_1 "1")
|
|
@ -45,6 +45,7 @@ macro(add_RunCMake_test test)
|
|||
)
|
||||
endmacro()
|
||||
|
||||
add_RunCMake_test(GeneratorExpression)
|
||||
add_RunCMake_test(Languages)
|
||||
add_RunCMake_test(ObjectLibrary)
|
||||
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,17 @@
|
|||
CMake Error at BadAND.cmake:1 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<AND:>
|
||||
|
||||
AND requires one or more comma-separated '0' or '1' values.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at BadAND.cmake:1 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<AND:,>
|
||||
|
||||
AND requires one or more comma-separated '0' or '1' values.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,4 @@
|
|||
add_custom_target(check ALL COMMAND check
|
||||
$<AND:>
|
||||
$<AND:,>
|
||||
VERBATIM)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,8 @@
|
|||
CMake Error at BadCONFIG.cmake:1 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<CONFIG:.>
|
||||
|
||||
Expression syntax not recognized.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,3 @@
|
|||
add_custom_target(check ALL COMMAND check
|
||||
$<CONFIG:.>
|
||||
VERBATIM)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,26 @@
|
|||
CMake Error at BadNOT.cmake:1 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<NOT:>
|
||||
|
||||
NOT requires exactly one '0' or '1' value.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at BadNOT.cmake:1 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<NOT:,>
|
||||
|
||||
NOT requires exactly one '0' or '1' value.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at BadNOT.cmake:1 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<NOT:0,1>
|
||||
|
||||
NOT requires exactly one '0' or '1' value.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,5 @@
|
|||
add_custom_target(check ALL COMMAND check
|
||||
$<NOT:>
|
||||
$<NOT:,>
|
||||
$<NOT:0,1>
|
||||
VERBATIM)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,17 @@
|
|||
CMake Error at BadOR.cmake:1 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<OR:>
|
||||
|
||||
OR requires one or more comma-separated '0' or '1' values.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at BadOR.cmake:1 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<OR:,>
|
||||
|
||||
OR requires one or more comma-separated '0' or '1' values.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)$
|
|
@ -0,0 +1,4 @@
|
|||
add_custom_target(check ALL COMMAND check
|
||||
$<OR:>
|
||||
$<OR:,>
|
||||
VERBATIM)
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,6 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(BadCONFIG)
|
||||
run_cmake(BadOR)
|
||||
run_cmake(BadAND)
|
||||
run_cmake(BadNOT)
|
Loading…
Reference in New Issue