Genex: Add COMPILE_LANG_AND_ID generator expression
This commit is contained in:
parent
f84ed796a2
commit
e214abdaab
@ -2199,6 +2199,7 @@ syn keyword cmakeGeneratorExpressions contained
|
||||
\ COMPILE_DEFINITIONS
|
||||
\ COMPILE_FEATURES
|
||||
\ COMPILE_LANGUAGE
|
||||
\ COMPILE_LANG_AND_ID
|
||||
\ COMPILING_CUDA
|
||||
\ COMPILING_CXX
|
||||
\ CONFIG
|
||||
|
@ -158,6 +158,42 @@ Variable Queries
|
||||
|
||||
.. _`Boolean COMPILE_LANGUAGE Generator Expression`:
|
||||
|
||||
``$<COMPILE_LANG_AND_ID:language,compiler_id>``
|
||||
``1`` when the language used for compilation unit matches ``language`` and
|
||||
the CMake's compiler id of the language compiler matches ``compiler_id``,
|
||||
otherwise ``0``. This expression is a short form for the combination of
|
||||
``$<COMPILE_LANGUAGE:language>`` and ``$<LANG_COMPILER_ID:compiler_id>``.
|
||||
This expression may be used to specify compile options,
|
||||
compile definitions, and include directories for source files of a
|
||||
particular language and compiler combination in a target. For example:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
add_executable(myapp main.cpp foo.c bar.cpp zot.cu)
|
||||
target_compile_definitions(myapp
|
||||
PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,Clang>:COMPILING_CXX_WITH_CLANG>
|
||||
$<$<COMPILE_LANG_AND_ID:CXX,Intel>:COMPILING_CXX_WITH_INTEL>
|
||||
$<$<COMPILE_LANG_AND_ID:C,Clang>:COMPILING_C_WITH_CLANG>
|
||||
)
|
||||
|
||||
This specifies the use of different compile definitions based on both
|
||||
the compiler id and compilation language. This example will have a
|
||||
``COMPILING_CXX_WITH_CLANG`` compile definition when Clang is the CXX
|
||||
compiler, and ``COMPILING_CXX_WITH_INTEL`` when Intel is the CXX compiler.
|
||||
Likewise when the C compiler is Clang it will only see the ``COMPILING_C_WITH_CLANG``
|
||||
definition.
|
||||
|
||||
Without the ``COMPILE_LANG_AND_ID`` generator expression the same logic
|
||||
would be expressed as:
|
||||
|
||||
.. code-block:: cmake
|
||||
|
||||
target_compile_definitions(myapp
|
||||
PRIVATE $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:Clang>>:COMPILING_CXX_WITH_CLANG>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CXX_COMPILER_ID:Intel>>:COMPILING_CXX_WITH_INTEL>
|
||||
$<$<AND:$<COMPILE_LANGUAGE:C>,$<C_COMPILER_ID:Clang>>:COMPILING_C_WITH_CLANG>
|
||||
)
|
||||
|
||||
``$<COMPILE_LANGUAGE:language>``
|
||||
``1`` when the language used for compilation unit matches ``language``,
|
||||
otherwise ``0``. This expression may be used to specify compile options,
|
||||
|
7
Help/release/dev/genex-COMPILE_LANG_AND_ID.rst
Normal file
7
Help/release/dev/genex-COMPILE_LANG_AND_ID.rst
Normal file
@ -0,0 +1,7 @@
|
||||
genex-COMPILE_LANG_AND_ID
|
||||
--------------------------
|
||||
|
||||
* A new ``COMPILE_LANG_AND_ID`` generator expression was introduced to
|
||||
allow specification of compile options for target files based on the
|
||||
:variable:`CMAKE_<LANG>_COMPILER_ID` and :prop_sf:`LANGUAGE` and of
|
||||
each source file.
|
@ -981,6 +981,51 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
|
||||
}
|
||||
} languageNode;
|
||||
|
||||
static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
|
||||
{
|
||||
CompileLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)
|
||||
|
||||
int NumExpectedParameters() const override { return 2; }
|
||||
|
||||
std::string Evaluate(
|
||||
const std::vector<std::string>& parameters,
|
||||
cmGeneratorExpressionContext* context,
|
||||
const GeneratorExpressionContent* content,
|
||||
cmGeneratorExpressionDAGChecker* dagChecker) const override
|
||||
{
|
||||
if (!context->HeadTarget || context->Language.empty()) {
|
||||
// reportError(context, content->GetOriginalExpression(), "");
|
||||
reportError(
|
||||
context, content->GetOriginalExpression(),
|
||||
"$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets "
|
||||
"to specify include directories, compile definitions, and compile "
|
||||
"options. It may not be used with the add_custom_command, "
|
||||
"add_custom_target, or file(GENERATE) commands.");
|
||||
return std::string();
|
||||
}
|
||||
cmGlobalGenerator* gg = context->LG->GetGlobalGenerator();
|
||||
std::string genName = gg->GetName();
|
||||
if (genName.find("Makefiles") == std::string::npos &&
|
||||
genName.find("Ninja") == std::string::npos &&
|
||||
genName.find("Visual Studio") == std::string::npos &&
|
||||
genName.find("Xcode") == std::string::npos &&
|
||||
genName.find("Watcom WMake") == std::string::npos) {
|
||||
reportError(
|
||||
context, content->GetOriginalExpression(),
|
||||
"$<COMPILE_LANG_AND_ID:lang,id> not supported for this generator.");
|
||||
return std::string();
|
||||
}
|
||||
|
||||
const std::string& lang = context->Language;
|
||||
if (lang == parameters.front()) {
|
||||
std::vector<std::string> idParameter = { parameters[1] };
|
||||
return CompilerIdNode{ lang.c_str() }.EvaluateWithLanguage(
|
||||
idParameter, context, content, dagChecker, lang);
|
||||
}
|
||||
return "0";
|
||||
}
|
||||
} languageAndIdNode;
|
||||
|
||||
#define TRANSITIVE_PROPERTY_NAME(PROPERTY) , "INTERFACE_" #PROPERTY
|
||||
|
||||
static const char* targetPropertyTransitiveWhitelist[] = {
|
||||
@ -2285,6 +2330,7 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
|
||||
{ "INSTALL_PREFIX", &installPrefixNode },
|
||||
{ "JOIN", &joinNode },
|
||||
{ "LINK_ONLY", &linkOnlyNode },
|
||||
{ "COMPILE_LANG_AND_ID", &languageAndIdNode },
|
||||
{ "COMPILE_LANGUAGE", &languageNode },
|
||||
{ "SHELL_PATH", &shellPathNode }
|
||||
};
|
||||
|
@ -8,7 +8,7 @@ add_executable(target_compile_options
|
||||
)
|
||||
target_compile_options(target_compile_options
|
||||
PRIVATE $<$<CXX_COMPILER_ID:GNU>:-DMY_PRIVATE_DEFINE>
|
||||
PUBLIC $<$<CXX_COMPILER_ID:GNU>:-DMY_PUBLIC_DEFINE>
|
||||
PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-DMY_PUBLIC_DEFINE>
|
||||
INTERFACE $<$<CXX_COMPILER_ID:GNU>:-DMY_INTERFACE_DEFINE>
|
||||
)
|
||||
|
||||
|
@ -25,6 +25,7 @@ set_property(TARGET CompileOptions PROPERTY COMPILE_OPTIONS
|
||||
"-DTEST_DEFINE"
|
||||
"-DNEEDS_ESCAPE=\"E$CAPE\""
|
||||
"$<$<CXX_COMPILER_ID:GNU>:-DTEST_DEFINE_GNU>"
|
||||
"$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-DTEST_DEFINE_CXX_AND_GNU>"
|
||||
"SHELL:" # produces no options
|
||||
${c_tests}
|
||||
${cxx_tests}
|
||||
|
@ -10,6 +10,9 @@
|
||||
# ifndef TEST_DEFINE_GNU
|
||||
# error Expected definition TEST_DEFINE_GNU
|
||||
# endif
|
||||
# ifndef TEST_DEFINE_CXX_AND_GNU
|
||||
# error Expected definition TEST_DEFINE_CXX_AND_GNU
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef NO_DEF_TESTS
|
||||
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,9 @@
|
||||
CMake Error at COMPILE_LANG_AND_ID-add_custom_command.cmake:2 \(add_custom_command\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<COMPILE_LANG_AND_ID>
|
||||
|
||||
\$<COMPILE_LANG_AND_ID> expression requires 2 comma separated parameters,
|
||||
but got 0 instead.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
@ -0,0 +1,4 @@
|
||||
add_custom_target(drive)
|
||||
add_custom_command(TARGET drive PRE_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANG_AND_ID>
|
||||
)
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,11 @@
|
||||
CMake Error at COMPILE_LANG_AND_ID-add_custom_target.cmake:2 \(add_custom_target\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:LANG,ID>
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
|
||||
specify include directories, compile definitions, and compile options. It
|
||||
may not be used with the add_custom_command, add_custom_target, or
|
||||
file\(GENERATE\) commands.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
@ -0,0 +1,4 @@
|
||||
|
||||
add_custom_target(drive
|
||||
COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANG_AND_ID:LANG,ID>
|
||||
)
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,11 @@
|
||||
CMake Error at COMPILE_LANG_AND_ID-add_executable.cmake:1 \(add_executable\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:C,MSVC>
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
|
||||
specify include directories, compile definitions, and compile options. It
|
||||
may not be used with the add_custom_command, add_custom_target, or
|
||||
file\(GENERATE\) commands.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
@ -0,0 +1,5 @@
|
||||
add_executable(empty main.c
|
||||
$<$<COMPILE_LANG_AND_ID:C,MSVC>:empty.c>
|
||||
$<$<COMPILE_LANG_AND_ID:C,GNU>:empty2.c>
|
||||
$<$<COMPILE_LANG_AND_ID:C,Clang>:empty3.c>
|
||||
)
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,11 @@
|
||||
CMake Error at COMPILE_LANG_AND_ID-add_library.cmake:2 \(add_library\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:C,MSVC>
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
|
||||
specify include directories, compile definitions, and compile options. It
|
||||
may not be used with the add_custom_command, add_custom_target, or
|
||||
file\(GENERATE\) commands.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
@ -0,0 +1,2 @@
|
||||
|
||||
add_library(empty empty.$<COMPILE_LANG_AND_ID:C,MSVC>)
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,11 @@
|
||||
CMake Error at COMPILE_LANG_AND_ID-add_test.cmake:5 \(add_test\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:CXX,GNU>
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
|
||||
specify include directories, compile definitions, and compile options. It
|
||||
may not be used with the add_custom_command, add_custom_target, or
|
||||
file\(GENERATE\) commands.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
@ -0,0 +1,5 @@
|
||||
|
||||
include(CTest)
|
||||
enable_testing()
|
||||
|
||||
add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<COMPILE_LANG_AND_ID:CXX,GNU>)
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,9 @@
|
||||
CMake Error:
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:C,MSVC>
|
||||
|
||||
\$<COMPILE_LANG_AND_ID:lang,id> may only be used with binary targets to
|
||||
specify include directories, compile definitions, and compile options. It
|
||||
may not be used with the add_custom_command, add_custom_target, or
|
||||
file\(GENERATE\) commands.
|
@ -0,0 +1,5 @@
|
||||
|
||||
install(FILES
|
||||
empty.$<COMPILE_LANG_AND_ID:C,MSVC>
|
||||
DESTINATION src
|
||||
)
|
@ -0,0 +1 @@
|
||||
1
|
@ -0,0 +1,9 @@
|
||||
CMake Error at COMPILE_LANG_AND_ID-target_sources.cmake:2 \(target_sources\):
|
||||
Error evaluating generator expression:
|
||||
|
||||
\$<COMPILE_LANG_AND_ID>
|
||||
|
||||
\$<COMPILE_LANG_AND_ID> expression requires 2 comma separated parameters,
|
||||
but got 0 instead.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
@ -0,0 +1,2 @@
|
||||
add_library(empty)
|
||||
target_sources(empty PRIVATE empty.$<COMPILE_LANG_AND_ID>)
|
@ -0,0 +1,4 @@
|
||||
|
||||
enable_language(C)
|
||||
add_executable(empty empty.c)
|
||||
target_compile_options(empty PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,GNU>:$<TARGET_EXISTS:too,many,parameters>>)
|
@ -31,6 +31,14 @@ run_cmake(COMPILE_LANGUAGE-add_executable)
|
||||
run_cmake(COMPILE_LANGUAGE-add_library)
|
||||
run_cmake(COMPILE_LANGUAGE-add_test)
|
||||
run_cmake(COMPILE_LANGUAGE-unknown-lang)
|
||||
run_cmake(COMPILE_LANG_AND_ID-add_custom_target)
|
||||
run_cmake(COMPILE_LANG_AND_ID-add_custom_command)
|
||||
run_cmake(COMPILE_LANG_AND_ID-install)
|
||||
run_cmake(COMPILE_LANG_AND_ID-target_sources)
|
||||
run_cmake(COMPILE_LANG_AND_ID-add_executable)
|
||||
run_cmake(COMPILE_LANG_AND_ID-add_library)
|
||||
run_cmake(COMPILE_LANG_AND_ID-add_test)
|
||||
run_cmake(COMPILE_LANG_AND_ID-unknown-lang)
|
||||
run_cmake(TARGET_FILE-recursion)
|
||||
run_cmake(OUTPUT_NAME-recursion)
|
||||
run_cmake(TARGET_FILE_PREFIX)
|
||||
|
Loading…
Reference in New Issue
Block a user