Browse Source

Genex: CompileLang and CompileLangAndId now match against a list of ids

This allows for expressions such as:

 $<COMPILE_LANG_AND_ID, CXX, GNU, Clang>
Robert Maynard 6 years ago
parent
commit
808b818063

+ 12 - 12
Help/manual/cmake-generator-expressions.7.rst

@@ -164,20 +164,20 @@ Variable Queries
 
 .. _`Boolean COMPILE_LANGUAGE Generator Expression`:
 
-``$<COMPILE_LANG_AND_ID:language,compiler_id>``
+``$<COMPILE_LANG_AND_ID:language,compiler_ids>``
   ``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
+  the CMake's compiler id of the language compiler matches any one of the
+  entries in ``compiler_ids``, otherwise ``0``. This expression is a short form
+  for the combination of ``$<COMPILE_LANGUAGE:language>`` and
+  ``$<LANG_COMPILER_ID:compiler_ids>``. 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>
+      PRIVATE $<$<COMPILE_LANG_AND_ID:CXX,AppleClang,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>
     )
@@ -200,10 +200,10 @@ Variable Queries
               $<$<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,
-  compile definitions, and include directories for source files of a
+``$<COMPILE_LANGUAGE:languages>``
+  ``1`` when the language used for compilation unit matches any of the entries
+  in ``languages``, otherwise ``0``.  This expression may be used to specify
+  compile options, compile definitions, and include directories for source files of a
   particular language in a target. For example:
 
   .. code-block:: cmake
@@ -217,7 +217,7 @@ Variable Queries
               $<$<COMPILE_LANGUAGE:CUDA>:COMPILING_CUDA>
     )
     target_include_directories(myapp
-      PRIVATE $<$<COMPILE_LANGUAGE:CXX>:/opt/foo/cxx_headers>
+      PRIVATE $<$<COMPILE_LANGUAGE:CXX,CUDA>:/opt/foo/headers>
     )
 
   This specifies the use of the ``-fno-exceptions`` compile option,

+ 11 - 4
Source/cmGeneratorExpressionNode.cxx

@@ -951,7 +951,7 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
 {
   CompileLanguageNode() {} // NOLINT(modernize-use-equals-default)
 
-  int NumExpectedParameters() const override { return OneOrZeroParameters; }
+  int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
 
   std::string Evaluate(
     const std::vector<std::string>& parameters,
@@ -982,7 +982,13 @@ static const struct CompileLanguageNode : public cmGeneratorExpressionNode
     if (parameters.empty()) {
       return context->Language;
     }
-    return context->Language == parameters.front() ? "1" : "0";
+
+    for (auto& param : parameters) {
+      if (context->Language == param) {
+        return "1";
+      }
+    }
+    return "0";
   }
 } languageNode;
 
@@ -990,7 +996,7 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
 {
   CompileLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)
 
-  int NumExpectedParameters() const override { return 2; }
+  int NumExpectedParameters() const override { return TwoOrMoreParameters; }
 
   std::string Evaluate(
     const std::vector<std::string>& parameters,
@@ -1023,7 +1029,8 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
 
     const std::string& lang = context->Language;
     if (lang == parameters.front()) {
-      std::vector<std::string> idParameter = { parameters[1] };
+      std::vector<std::string> idParameter((parameters.cbegin() + 1),
+                                           parameters.cend());
       return CompilerIdNode{ lang.c_str() }.EvaluateWithLanguage(
         idParameter, context, content, dagChecker, lang);
     }

+ 1 - 0
Tests/CMakeCommands/target_compile_definitions/CMakeLists.txt

@@ -34,6 +34,7 @@ target_compile_definitions(consumer
     CONSUMER_LANG_$<COMPILE_LANGUAGE>
     LANG_IS_CXX=$<COMPILE_LANGUAGE:CXX>
     LANG_IS_C=$<COMPILE_LANGUAGE:C>
+    LANG_IS_C_OR_CXX=$<COMPILE_LANGUAGE:C,CXX>
 )
 if(CMAKE_GENERATOR MATCHES "Visual Studio|Xcode")
   target_compile_definitions(consumer

+ 4 - 0
Tests/CMakeCommands/target_compile_definitions/consumer.c

@@ -35,6 +35,10 @@
 #  endif
 #endif
 
+#if !LANG_IS_C_OR_CXX
+#  error Expected LANG_IS_C_OR_CXX
+#endif
+
 void consumer_c()
 {
 }

+ 1 - 0
Tests/CMakeCommands/target_compile_options/CMakeLists.txt

@@ -9,6 +9,7 @@ add_executable(target_compile_options
 target_compile_options(target_compile_options
   PRIVATE $<$<CXX_COMPILER_ID:AppleClang,Clang,GNU>:-DMY_PRIVATE_DEFINE>
   PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU>:-DMY_PUBLIC_DEFINE>
+  PUBLIC $<$<COMPILE_LANG_AND_ID:CXX,GNU,Clang,AppleClang>:-DMY_MUTLI_COMP_PUBLIC_DEFINE>
   INTERFACE $<$<CXX_COMPILER_ID:GNU>:-DMY_INTERFACE_DEFINE>
   INTERFACE $<$<CXX_COMPILER_ID:GNU,Clang,AppleClang>:-DMY_MULTI_COMP_INTERFACE_DEFINE>
 )

+ 8 - 0
Tests/CMakeCommands/target_compile_options/consumer.cpp

@@ -17,6 +17,10 @@
 #    error Expected MY_MULTI_COMP_INTERFACE_DEFINE
 #  endif
 
+#  ifndef MY_MUTLI_COMP_PUBLIC_DEFINE
+#    error Expected MY_MUTLI_COMP_PUBLIC_DEFINE
+#  endif
+
 #endif
 
 #ifdef DO_CLANG_TESTS
@@ -29,6 +33,10 @@
 #    error Expected MY_MULTI_COMP_INTERFACE_DEFINE
 #  endif
 
+#  ifndef MY_MUTLI_COMP_PUBLIC_DEFINE
+#    error Expected MY_MUTLI_COMP_PUBLIC_DEFINE
+#  endif
+
 #endif
 
 #ifndef CONSUMER_LANG_CXX

+ 8 - 0
Tests/CMakeCommands/target_compile_options/main.cpp

@@ -9,6 +9,10 @@
 #    error Expected MY_PUBLIC_DEFINE
 #  endif
 
+#  ifndef MY_MUTLI_COMP_PUBLIC_DEFINE
+#    error Expected MY_MUTLI_COMP_PUBLIC_DEFINE
+#  endif
+
 #  ifdef MY_INTERFACE_DEFINE
 #    error Unexpected MY_INTERFACE_DEFINE
 #  endif
@@ -25,6 +29,10 @@
 #    error Unexpected MY_PUBLIC_DEFINE
 #  endif
 
+#  ifndef MY_MUTLI_COMP_PUBLIC_DEFINE
+#    error Expected MY_MUTLI_COMP_PUBLIC_DEFINE
+#  endif
+
 #endif
 
 int main()

+ 1 - 2
Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-add_custom_command-stderr.txt

@@ -3,7 +3,6 @@ CMake Error at COMPILE_LANG_AND_ID-add_custom_command.cmake:2 \(add_custom_comma
 
     \$<COMPILE_LANG_AND_ID>
 
-  \$<COMPILE_LANG_AND_ID> expression requires 2 comma separated parameters,
-  but got 0 instead.
+  \$<COMPILE_LANG_AND_ID> expression requires at least two parameters.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)

+ 1 - 2
Tests/RunCMake/GeneratorExpression/COMPILE_LANG_AND_ID-target_sources-stderr.txt

@@ -3,7 +3,6 @@ CMake Error at COMPILE_LANG_AND_ID-target_sources.cmake:2 \(target_sources\):
 
     \$<COMPILE_LANG_AND_ID>
 
-  \$<COMPILE_LANG_AND_ID> expression requires 2 comma separated parameters,
-  but got 0 instead.
+  \$<COMPILE_LANG_AND_ID> expression requires at least two parameters.
 Call Stack \(most recent call first\):
   CMakeLists.txt:3 \(include\)