summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst114
-rw-r--r--Help/release/dev/genex-LINK_LANGUAGE.rst5
-rw-r--r--Source/cmGeneratorExpression.cxx3
-rw-r--r--Source/cmGeneratorExpression.h5
-rw-r--r--Source/cmGeneratorExpressionContext.cxx1
-rw-r--r--Source/cmGeneratorExpressionContext.h1
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx34
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h1
-rw-r--r--Source/cmGeneratorExpressionNode.cxx149
-rw-r--r--Source/cmGeneratorTarget.cxx164
-rw-r--r--Source/cmGeneratorTarget.h27
-rw-r--r--Source/cmLinkItem.h6
-rw-r--r--Tests/BuildDepends/CMakeLists.txt22
-rw-r--r--Tests/BuildDepends/Project/CMakeLists.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt (renamed from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt)0
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target.cmake3
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library.cmake1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-unknown-lang.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4.cmake7
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-stderr.txt10
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install.cmake5
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-stderr.txt8
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources.cmake2
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-unknown-lang.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-result.txt1
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-stderr.txt9
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3.cmake4
-rw-r--r--Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake25
-rw-r--r--Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt1
-rw-r--r--Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt (renamed from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt)2
-rw-r--r--Tests/RunCMake/Languages/LINKER_LANGUAGE-genex.cmake (renamed from Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake)0
-rw-r--r--Tests/RunCMake/Languages/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake16
-rw-r--r--Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/LinkOptionsLib.cxx7
-rw-r--r--Tests/RunCMake/add_link_options/RunCMakeTest.cmake15
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake17
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake17
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake2
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake5
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt1
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake23
-rw-r--r--Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake19
-rw-r--r--Tests/RunCMake/target_link_directories/CMP0099.cmake2
-rw-r--r--Tests/RunCMake/target_link_directories/RunCMakeTest.cmake13
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-validation.cmake20
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE.cmake23
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-check.cmake4
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-validation.cmake26
-rw-r--r--Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID.cmake29
-rw-r--r--Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake54
-rw-r--r--Tests/RunCMake/target_link_libraries/func.c7
-rw-r--r--Tests/RunCMake/target_link_libraries/func.cxx7
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-stderr.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang.cmake8
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-stderr.txt8
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage.cmake4
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE.cmake72
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-stderr.txt2
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang.cmake8
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-basic-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_c-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_cxx-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-no_language-result.txt1
-rw-r--r--Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID.cmake73
-rw-r--r--Tests/RunCMake/target_link_libraries/lib.c10
-rw-r--r--Tests/RunCMake/target_link_libraries/main.c12
-rw-r--r--Tests/RunCMake/target_link_libraries/main.cxx12
-rw-r--r--Tests/RunCMake/target_link_options/RunCMakeTest.cmake17
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-validation.cmake17
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE.cmake32
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake2
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake5
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt1
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-validation.cmake23
-rw-r--r--Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID.cmake41
182 files changed, 1619 insertions, 55 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 691481b..402da70 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -259,6 +259,109 @@ Variable Queries
add_executable(myapp main.cpp)
target_link_libraries(myapp myapp_c myapp_cxx)
+.. _`Boolean LINK_LANGUAGE Generator Expression`:
+
+``$<LINK_LANG_AND_ID:language,compiler_ids>``
+ ``1`` when the language used for link step matches ``language`` and the
+ CMake's compiler id of the language linker matches any one of the entries
+ in ``compiler_ids``, otherwise ``0``. This expression is a short form for the
+ combination of ``$<LINK_LANGUAGE:language>`` and
+ ``$<LANG_COMPILER_ID:compiler_ids>``. This expression may be used to specify
+ link libraries, link options, link directories and link dependencies of a
+ particular language and linker combination in a target. For example:
+
+ .. code-block:: cmake
+
+ add_library(libC_Clang ...)
+ add_library(libCXX_Clang ...)
+ add_library(libC_Intel ...)
+ add_library(libCXX_Intel ...)
+
+ add_executable(myapp main.c)
+ if (CXX_CONFIG)
+ target_sources(myapp PRIVATE file.cxx)
+ endif()
+ target_link_libraries(myapp
+ PRIVATE $<$<LINK_LANG_AND_ID:CXX,Clang,AppleClang>:libCXX_Clang>
+ $<$<LINK_LANG_AND_ID:C,Clang,AppleClang>:libC_Clang>
+ $<$<LINK_LANG_AND_ID:CXX,Intel>:libCXX_Intel>
+ $<$<LINK_LANG_AND_ID:C,Intel>:libC_Intel>)
+
+ This specifies the use of different link libraries based on both the
+ compiler id and link language. This example will have target ``libCXX_Clang``
+ as link dependency when ``Clang`` or ``AppleClang`` is the ``CXX``
+ linker, and ``libCXX_Intel`` when ``Intel`` is the ``CXX`` linker.
+ Likewise when the ``C`` linker is ``Clang`` or ``AppleClang``, target
+ ``libC_Clang`` will be added as link dependency and ``libC_Intel`` when
+ ``Intel`` is the ``C`` linker.
+
+ See :ref:`the note related to
+ <Constraints LINK_LANGUAGE Generator Expression>`
+ ``$<LINK_LANGUAGE:language>`` for constraints about the usage of this
+ generator expression.
+
+``$<LINK_LANGUAGE:languages>``
+ ``1`` when the language used for link step matches any of the entries
+ in ``languages``, otherwise ``0``. This expression may be used to specify
+ link libraries, link options, link directories and link dependencies of a
+ particular language in a target. For example:
+
+ .. code-block:: cmake
+
+ add_library(api_C ...)
+ add_library(api_CXX ...)
+ add_library(api INTERFACE)
+ target_link_options(api INTERFACE $<$<LINK_LANGUAGE:C>:-opt_c>
+ $<$<LINK_LANGUAGE:CXX>:-opt_cxx>)
+ target_link_libraries(api INTERFACE $<$<LINK_LANGUAGE:C>:api_C>
+ $<$<LINK_LANGUAGE:CXX>:api_CXX>)
+
+ add_executable(myapp1 main.c)
+ target_link_options(myapp1 PRIVATE api)
+
+ add_executable(myapp2 main.cpp)
+ target_link_options(myapp2 PRIVATE api)
+
+ This specifies to use the ``api`` target for linking targets ``myapp1`` and
+ ``myapp2``. In practice, ``myapp1`` will link with target ``api_C`` and
+ option ``-opt_c`` because it will use ``C`` as link language. And ``myapp2``
+ will link with ``api_CXX`` and option ``-opt_cxx`` because ``CXX`` will be
+ the link language.
+
+ .. _`Constraints LINK_LANGUAGE Generator Expression`:
+
+ .. note::
+
+ To determine the link language of a target, it is required to collect,
+ transitively, all the targets which will be linked to it. So, for link
+ libraries properties, a double evaluation will be done. During the first
+ evaluation, ``$<LINK_LANGUAGE:..>`` expressions will always return ``0``.
+ The link language computed after this first pass will be used to do the
+ second pass. To avoid inconsistency, it is required that the second pass
+ do not change the link language. Moreover, to avoid unexpected
+ side-effects, it is required to specify complete entities as part of the
+ ``$<LINK_LANGUAGE:..>`` expression. For example:
+
+ .. code-block:: cmake
+
+ add_library(lib STATIC file.cxx)
+ add_library(libother STATIC file.c)
+
+ # bad usage
+ add_executable(myapp1 main.c)
+ target_link_libraries(myapp1 PRIVATE lib$<$<LINK_LANGUAGE:C>:other>)
+
+ # correct usage
+ add_executable(myapp2 main.c)
+ target_link_libraries(myapp2 PRIVATE $<$<LINK_LANGUAGE:C>:libother>)
+
+ In this example, for ``myapp1``, the first pass will, unexpectedly,
+ determine that the link language is ``CXX`` because the evaluation of the
+ generator expression will be an empty string so ``myapp1`` will depends on
+ target ``lib`` which is ``C++``. On the contrary, for ``myapp2``, the first
+ evaluation will give ``C`` as link language, so the second pass will
+ correctly add target ``libother`` as link dependency.
+
String-Valued Generator Expressions
===================================
@@ -450,6 +553,17 @@ Variable Queries
<Boolean COMPILE_LANGUAGE Generator Expression>`
``$<COMPILE_LANGUAGE:language>``
for notes about the portability of this generator expression.
+``$<LINK_LANGUAGE>``
+ The link language of target when evaluating link options.
+ See :ref:`the related boolean expression
+ <Boolean LINK_LANGUAGE Generator Expression>` ``$<LINK_LANGUAGE:language>``
+ for notes about the portability of this generator expression.
+
+ .. note::
+
+ This generator expression is not supported by the link libraries
+ properties to avoid side-effects due to the double evaluation of
+ these properties.
Target-Dependent Queries
------------------------
diff --git a/Help/release/dev/genex-LINK_LANGUAGE.rst b/Help/release/dev/genex-LINK_LANGUAGE.rst
new file mode 100644
index 0000000..05894d6
--- /dev/null
+++ b/Help/release/dev/genex-LINK_LANGUAGE.rst
@@ -0,0 +1,5 @@
+genex-LINK_LANGUAGE
+===================
+
+* The ``$<LINK_LANGUAGE:...>`` and ``$<LINK_LANG_AND_ID:...>``
+ :manual:`generator expressions <cmake-generator-expressions(7)>` were added.
diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx
index 81d1e46..03c2a0c 100644
--- a/Source/cmGeneratorExpression.cxx
+++ b/Source/cmGeneratorExpression.cxx
@@ -103,6 +103,8 @@ const std::string& cmCompiledGeneratorExpression::EvaluateWithContext(
if (!context.HadError) {
this->HadContextSensitiveCondition = context.HadContextSensitiveCondition;
this->HadHeadSensitiveCondition = context.HadHeadSensitiveCondition;
+ this->HadLinkLanguageSensitiveCondition =
+ context.HadLinkLanguageSensitiveCondition;
this->SourceSensitiveTargets = context.SourceSensitiveTargets;
}
@@ -119,6 +121,7 @@ cmCompiledGeneratorExpression::cmCompiledGeneratorExpression(
, Quiet(false)
, HadContextSensitiveCondition(false)
, HadHeadSensitiveCondition(false)
+ , HadLinkLanguageSensitiveCondition(false)
{
cmGeneratorExpressionLexer l;
std::vector<cmGeneratorExpressionToken> tokens = l.Tokenize(this->Input);
diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h
index c4be3a1..a0e40c3 100644
--- a/Source/cmGeneratorExpression.h
+++ b/Source/cmGeneratorExpression.h
@@ -137,6 +137,10 @@ public:
{
return this->HadHeadSensitiveCondition;
}
+ bool GetHadLinkLanguageSensitiveCondition() const
+ {
+ return this->HadLinkLanguageSensitiveCondition;
+ }
std::set<cmGeneratorTarget const*> GetSourceSensitiveTargets() const
{
return this->SourceSensitiveTargets;
@@ -178,6 +182,7 @@ private:
mutable std::string Output;
mutable bool HadContextSensitiveCondition;
mutable bool HadHeadSensitiveCondition;
+ mutable bool HadLinkLanguageSensitiveCondition;
mutable std::set<cmGeneratorTarget const*> SourceSensitiveTargets;
};
diff --git a/Source/cmGeneratorExpressionContext.cxx b/Source/cmGeneratorExpressionContext.cxx
index 6d97331..42cbe2a 100644
--- a/Source/cmGeneratorExpressionContext.cxx
+++ b/Source/cmGeneratorExpressionContext.cxx
@@ -19,6 +19,7 @@ cmGeneratorExpressionContext::cmGeneratorExpressionContext(
, HadError(false)
, HadContextSensitiveCondition(false)
, HadHeadSensitiveCondition(false)
+ , HadLinkLanguageSensitiveCondition(false)
, EvaluateForBuildsystem(evaluateForBuildsystem)
{
}
diff --git a/Source/cmGeneratorExpressionContext.h b/Source/cmGeneratorExpressionContext.h
index 4709fa0..bceff12 100644
--- a/Source/cmGeneratorExpressionContext.h
+++ b/Source/cmGeneratorExpressionContext.h
@@ -40,6 +40,7 @@ struct cmGeneratorExpressionContext
bool HadError;
bool HadContextSensitiveCondition;
bool HadHeadSensitiveCondition;
+ bool HadLinkLanguageSensitiveCondition;
bool EvaluateForBuildsystem;
};
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 643ba34..2c73289 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -6,6 +6,10 @@
#include <sstream>
#include <utility>
+#include <cm/string_view>
+
+#include "cm_static_string_view.hxx"
+
#include "cmGeneratorExpressionContext.h"
#include "cmGeneratorExpressionEvaluator.h"
#include "cmGeneratorTarget.h"
@@ -170,6 +174,21 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression()
return top->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
}
+bool cmGeneratorExpressionDAGChecker::EvaluatingLinkExpression()
+{
+ const cmGeneratorExpressionDAGChecker* top = this;
+ const cmGeneratorExpressionDAGChecker* parent = this->Parent;
+ while (parent) {
+ top = parent;
+ parent = parent->Parent;
+ }
+
+ cm::string_view property(top->Property);
+
+ return property == "LINK_DIRECTORIES"_s || property == "LINK_OPTIONS"_s ||
+ property == "LINK_DEPENDS"_s;
+}
+
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
cmGeneratorTarget const* tgt)
{
@@ -180,18 +199,17 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
parent = parent->Parent;
}
- const char* prop = top->Property.c_str();
+ cm::string_view prop(top->Property);
if (tgt) {
- return top->Target == tgt && strcmp(prop, "LINK_LIBRARIES") == 0;
+ return top->Target == tgt && prop == "LINK_LIBRARIES"_s;
}
- return (strcmp(prop, "LINK_LIBRARIES") == 0 ||
- strcmp(prop, "LINK_INTERFACE_LIBRARIES") == 0 ||
- strcmp(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES") == 0 ||
- cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
- cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_")) ||
- strcmp(prop, "INTERFACE_LINK_LIBRARIES") == 0;
+ return prop == "LINK_LIBRARIES"_s || prop == "LINK_INTERFACE_LIBRARIES"_s ||
+ prop == "IMPORTED_LINK_INTERFACE_LIBRARIES"_s ||
+ cmHasLiteralPrefix(prop, "LINK_INTERFACE_LIBRARIES_") ||
+ cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LIBRARIES_") ||
+ prop == "INTERFACE_LINK_LIBRARIES"_s;
}
cmGeneratorTarget const* cmGeneratorExpressionDAGChecker::TopTarget() const
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index f2c49bb..2a06596 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -68,6 +68,7 @@ struct cmGeneratorExpressionDAGChecker
bool EvaluatingGenexExpression();
bool EvaluatingPICExpression();
+ bool EvaluatingLinkExpression();
bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr);
#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index 14478c2..8831d0f 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -62,6 +62,9 @@ std::string cmGeneratorExpressionNode::EvaluateDependentExpression(
if (cge->GetHadHeadSensitiveCondition()) {
context->HadHeadSensitiveCondition = true;
}
+ if (cge->GetHadLinkLanguageSensitiveCondition()) {
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
return result;
}
@@ -1039,6 +1042,150 @@ static const struct CompileLanguageAndIdNode : public cmGeneratorExpressionNode
}
} languageAndIdNode;
+static const struct LinkLanguageNode : public cmGeneratorExpressionNode
+{
+ LinkLanguageNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return ZeroOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !(dagChecker->EvaluatingLinkExpression() ||
+ dagChecker->EvaluatingLinkLibraries())) {
+ reportError(context, content->GetOriginalExpression(),
+ "$<LINK_LANGUAGE:...> may only be used with binary targets "
+ "to specify link libraries, link directories, link options "
+ "and link depends.");
+ return std::string();
+ }
+ if (dagChecker->EvaluatingLinkLibraries() && parameters.empty()) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LANGUAGE> is not supported in link libraries expression.");
+ 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(),
+ "$<LINK_LANGUAGE:...> not supported for this generator.");
+ return std::string();
+ }
+
+ if (dagChecker->EvaluatingLinkLibraries()) {
+ context->HadHeadSensitiveCondition = true;
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
+
+ if (parameters.empty()) {
+ return context->Language;
+ }
+
+ for (auto& param : parameters) {
+ if (context->Language == param) {
+ return "1";
+ }
+ }
+ return "0";
+ }
+} linkLanguageNode;
+
+namespace {
+struct LinkerId
+{
+ static std::string Evaluate(const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ const std::string& lang)
+ {
+ std::string const& linkerId =
+ context->LG->GetMakefile()->GetSafeDefinition("CMAKE_" + lang +
+ "_COMPILER_ID");
+ if (parameters.empty()) {
+ return linkerId;
+ }
+ if (linkerId.empty()) {
+ return parameters.front().empty() ? "1" : "0";
+ }
+ static cmsys::RegularExpression linkerIdValidator("^[A-Za-z0-9_]*$");
+
+ for (auto& param : parameters) {
+ if (!linkerIdValidator.find(param)) {
+ reportError(context, content->GetOriginalExpression(),
+ "Expression syntax not recognized.");
+ return std::string();
+ }
+
+ if (param == linkerId) {
+ return "1";
+ }
+ }
+ return "0";
+ }
+};
+}
+
+static const struct LinkLanguageAndIdNode : public cmGeneratorExpressionNode
+{
+ LinkLanguageAndIdNode() {} // NOLINT(modernize-use-equals-default)
+
+ int NumExpectedParameters() const override { return TwoOrMoreParameters; }
+
+ std::string Evaluate(
+ const std::vector<std::string>& parameters,
+ cmGeneratorExpressionContext* context,
+ const GeneratorExpressionContent* content,
+ cmGeneratorExpressionDAGChecker* dagChecker) const override
+ {
+ if (!context->HeadTarget || !dagChecker ||
+ !(dagChecker->EvaluatingLinkExpression() ||
+ dagChecker->EvaluatingLinkLibraries())) {
+ reportError(
+ context, content->GetOriginalExpression(),
+ "$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets "
+ "to specify link libraries, link directories, link options, and link "
+ "depends.");
+ 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(),
+ "$<LINK_LANG_AND_ID:lang,id> not supported for this generator.");
+ return std::string();
+ }
+
+ if (dagChecker->EvaluatingLinkLibraries()) {
+ context->HadHeadSensitiveCondition = true;
+ context->HadLinkLanguageSensitiveCondition = true;
+ }
+
+ const std::string& lang = context->Language;
+ if (lang == parameters.front()) {
+ std::vector<std::string> idParameter((parameters.cbegin() + 1),
+ parameters.cend());
+ return LinkerId::Evaluate(idParameter, context, content, lang);
+ }
+ return "0";
+ }
+} linkLanguageAndIdNode;
+
std::string getLinkedTargetsContent(
cmGeneratorTarget const* target, std::string const& prop,
cmGeneratorExpressionContext* context,
@@ -2314,6 +2461,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode(
{ "LINK_ONLY", &linkOnlyNode },
{ "COMPILE_LANG_AND_ID", &languageAndIdNode },
{ "COMPILE_LANGUAGE", &languageNode },
+ { "LINK_LANG_AND_ID", &linkLanguageAndIdNode },
+ { "LINK_LANGUAGE", &linkLanguageNode },
{ "SHELL_PATH", &shellPathNode }
};
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 5ef882c..95b1c54 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -17,6 +17,7 @@
#include <cm/memory>
#include <cm/string_view>
+#include <cmext/algorithm>
#include "cmsys/RegularExpression.hxx"
@@ -307,6 +308,13 @@ cmGeneratorTarget::cmGeneratorTarget(cmTarget* t, cmLocalGenerator* lg)
this->SourceEntries, true);
this->PolicyMap = t->GetPolicyMap();
+
+ // Get hard-coded linker language
+ if (this->Target->GetProperty("HAS_CXX")) {
+ this->LinkerLanguage = "CXX";
+ } else {
+ this->LinkerLanguage = this->Target->GetSafeProperty("LINKER_LANGUAGE");
+ }
}
cmGeneratorTarget::~cmGeneratorTarget() = default;
@@ -2222,11 +2230,12 @@ public:
cmTargetCollectLinkLanguages(cmGeneratorTarget const* target,
std::string config,
std::unordered_set<std::string>& languages,
- cmGeneratorTarget const* head)
+ cmGeneratorTarget const* head, bool secondPass)
: Config(std::move(config))
, Languages(languages)
, HeadTarget(head)
, Target(target)
+ , SecondPass(secondPass)
{
this->Visited.insert(target);
}
@@ -2268,11 +2277,14 @@ public:
if (!this->Visited.insert(item.Target).second) {
return;
}
- cmLinkInterface const* iface =
- item.Target->GetLinkInterface(this->Config, this->HeadTarget);
+ cmLinkInterface const* iface = item.Target->GetLinkInterface(
+ this->Config, this->HeadTarget, this->SecondPass);
if (!iface) {
return;
}
+ if (iface->HadLinkLanguageSensitiveCondition) {
+ this->HadLinkLanguageSensitiveCondition = true;
+ }
for (std::string const& language : iface->Languages) {
this->Languages.insert(language);
@@ -2283,12 +2295,19 @@ public:
}
}
+ bool GetHadLinkLanguageSensitiveCondition()
+ {
+ return HadLinkLanguageSensitiveCondition;
+ }
+
private:
std::string Config;
std::unordered_set<std::string>& Languages;
cmGeneratorTarget const* HeadTarget;
const cmGeneratorTarget* Target;
std::set<cmGeneratorTarget const*> Visited;
+ bool SecondPass;
+ bool HadLinkLanguageSensitiveCondition = false;
};
cmGeneratorTarget::LinkClosure const* cmGeneratorTarget::GetLinkClosure(
@@ -2319,7 +2338,7 @@ public:
{
this->GG = this->Target->GetLocalGenerator()->GetGlobalGenerator();
}
- void Consider(const char* lang)
+ void Consider(const std::string& lang)
{
int preference = this->GG->GetLinkerPreference(lang);
if (preference > this->Preference) {
@@ -2352,40 +2371,36 @@ public:
}
};
-void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
- LinkClosure& lc) const
+bool cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc,
+ bool secondPass) const
{
// Get languages built in this target.
std::unordered_set<std::string> languages;
- cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config, secondPass);
assert(impl);
- for (std::string const& li : impl->Languages) {
- languages.insert(li);
- }
+ languages.insert(impl->Languages.cbegin(), impl->Languages.cend());
// Add interface languages from linked targets.
- cmTargetCollectLinkLanguages cll(this, config, languages, this);
+ // cmTargetCollectLinkLanguages cll(this, config, languages, this,
+ // secondPass);
+ cmTargetCollectLinkLanguages cll(this, config, languages, this, secondPass);
for (cmLinkImplItem const& lib : impl->Libraries) {
cll.Visit(lib);
}
// Store the transitive closure of languages.
- for (std::string const& lang : languages) {
- lc.Languages.push_back(lang);
- }
+ cm::append(lc.Languages, languages);
// Choose the language whose linker should be used.
- if (this->GetProperty("HAS_CXX")) {
- lc.LinkerLanguage = "CXX";
- } else if (const char* linkerLang = this->GetProperty("LINKER_LANGUAGE")) {
- lc.LinkerLanguage = linkerLang;
- } else {
+ if (secondPass || lc.LinkerLanguage.empty()) {
// Find the language with the highest preference value.
cmTargetSelectLinker tsl(this);
// First select from the languages compiled directly in this target.
for (std::string const& l : impl->Languages) {
- tsl.Consider(l.c_str());
+ tsl.Consider(l);
}
// Now consider languages that propagate from linked targets.
@@ -2393,12 +2408,50 @@ void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
std::string propagates =
"CMAKE_" + lang + "_LINKER_PREFERENCE_PROPAGATES";
if (this->Makefile->IsOn(propagates)) {
- tsl.Consider(lang.c_str());
+ tsl.Consider(lang);
}
}
lc.LinkerLanguage = tsl.Choose();
}
+
+ return impl->HadLinkLanguageSensitiveCondition ||
+ cll.GetHadLinkLanguageSensitiveCondition();
+}
+
+void cmGeneratorTarget::ComputeLinkClosure(const std::string& config,
+ LinkClosure& lc) const
+{
+ bool secondPass = false;
+
+ {
+ LinkClosure linkClosure;
+ linkClosure.LinkerLanguage = this->LinkerLanguage;
+
+ // Get languages built in this target.
+ secondPass = this->ComputeLinkClosure(config, linkClosure, false);
+ this->LinkerLanguage = linkClosure.LinkerLanguage;
+ if (!secondPass) {
+ lc = std::move(linkClosure);
+ }
+ }
+
+ if (secondPass) {
+ LinkClosure linkClosure;
+
+ this->ComputeLinkClosure(config, linkClosure, secondPass);
+ lc = std::move(linkClosure);
+
+ // linker language must not be changed between the two passes
+ if (this->LinkerLanguage != lc.LinkerLanguage) {
+ std::ostringstream e;
+ e << "Evaluation of $<LINK_LANGUAGE:...> or $<LINK_LAND_AND_ID:...> "
+ "changes\nthe linker language for target \""
+ << this->GetName() << "\" (from '" << this->LinkerLanguage << "' to '"
+ << lc.LinkerLanguage << "') which is invalid.";
+ cmSystemTools::Error(e.str());
+ }
+ }
}
void cmGeneratorTarget::GetFullNameComponents(
@@ -5479,7 +5532,8 @@ void cmGeneratorTarget::LookupLinkItems(std::vector<std::string> const& names,
void cmGeneratorTarget::ExpandLinkItems(
std::string const& prop, std::string const& value, std::string const& config,
cmGeneratorTarget const* headTarget, bool usage_requirements_only,
- std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition) const
+ std::vector<cmLinkItem>& items, bool& hadHeadSensitiveCondition,
+ bool& hadLinkLanguageSensitiveCondition) const
{
// Keep this logic in sync with ComputeLinkImplementationLibraries.
cmGeneratorExpression ge;
@@ -5491,19 +5545,28 @@ void cmGeneratorTarget::ExpandLinkItems(
}
std::vector<std::string> libs;
std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(value);
- cmExpandList(
- cge->Evaluate(this->LocalGenerator, config, headTarget, &dagChecker, this),
- libs);
+ cmExpandList(cge->Evaluate(this->LocalGenerator, config, headTarget,
+ &dagChecker, this, headTarget->LinkerLanguage),
+ libs);
this->LookupLinkItems(libs, cge->GetBacktrace(), items);
hadHeadSensitiveCondition = cge->GetHadHeadSensitiveCondition();
+ hadLinkLanguageSensitiveCondition =
+ cge->GetHadLinkLanguageSensitiveCondition();
}
cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
const std::string& config, cmGeneratorTarget const* head) const
{
+ return this->GetLinkInterface(config, head, false);
+}
+
+cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
+ const std::string& config, cmGeneratorTarget const* head,
+ bool secondPass) const
+{
// Imported targets have their own link interface.
if (this->IsImported()) {
- return this->GetImportLinkInterface(config, head, false);
+ return this->GetImportLinkInterface(config, head, false, secondPass);
}
// Link interfaces are not supported for executables that do not
@@ -5516,6 +5579,10 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
// Lookup any existing link interface for this configuration.
cmHeadToLinkInterfaceMap& hm = this->GetHeadToLinkInterfaceMap(config);
+ if (secondPass) {
+ hm.erase(head);
+ }
+
// If the link interface does not depend on the head target
// then return the one we computed first.
if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) {
@@ -5530,7 +5597,7 @@ cmLinkInterface const* cmGeneratorTarget::GetLinkInterface(
if (!iface.AllDone) {
iface.AllDone = true;
if (iface.Exists) {
- this->ComputeLinkInterface(config, iface, head);
+ this->ComputeLinkInterface(config, iface, head, secondPass);
}
}
@@ -5541,6 +5608,13 @@ void cmGeneratorTarget::ComputeLinkInterface(
const std::string& config, cmOptionalLinkInterface& iface,
cmGeneratorTarget const* headTarget) const
{
+ this->ComputeLinkInterface(config, iface, headTarget, false);
+}
+
+void cmGeneratorTarget::ComputeLinkInterface(
+ const std::string& config, cmOptionalLinkInterface& iface,
+ cmGeneratorTarget const* headTarget, bool secondPass) const
+{
if (iface.Explicit) {
if (this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::STATIC_LIBRARY ||
@@ -5552,7 +5626,8 @@ void cmGeneratorTarget::ComputeLinkInterface(
emitted.insert(lib);
}
if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
- cmLinkImplementation const* impl = this->GetLinkImplementation(config);
+ cmLinkImplementation const* impl =
+ this->GetLinkImplementation(config, secondPass);
for (cmLinkImplItem const& lib : impl->Libraries) {
if (emitted.insert(lib).second) {
if (lib.Target) {
@@ -5582,7 +5657,7 @@ void cmGeneratorTarget::ComputeLinkInterface(
if (this->LinkLanguagePropagatesToDependents()) {
// Targets using this archive need its language runtime libraries.
if (cmLinkImplementation const* impl =
- this->GetLinkImplementation(config)) {
+ this->GetLinkImplementation(config, secondPass)) {
iface.Languages = impl->Languages;
}
}
@@ -5978,7 +6053,8 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
// The interface libraries have been explicitly set.
this->ExpandLinkItems(linkIfaceProp, explicitLibraries, config, headTarget,
usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition);
+ iface.HadHeadSensitiveCondition,
+ iface.HadLinkLanguageSensitiveCondition);
} else if (!cmp0022NEW)
// If CMP0022 is NEW then the plain tll signature sets the
// INTERFACE_LINK_LIBRARIES, so if we get here then the project
@@ -5998,9 +6074,11 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
static const std::string newProp = "INTERFACE_LINK_LIBRARIES";
if (const char* newExplicitLibraries = this->GetProperty(newProp)) {
bool hadHeadSensitiveConditionDummy = false;
+ bool hadLinkLanguageSensitiveConditionDummy = false;
this->ExpandLinkItems(newProp, newExplicitLibraries, config,
headTarget, usage_requirements_only, ifaceLibs,
- hadHeadSensitiveConditionDummy);
+ hadHeadSensitiveConditionDummy,
+ hadLinkLanguageSensitiveConditionDummy);
}
if (ifaceLibs != iface.Libraries) {
std::string oldLibraries = cmJoin(impl->Libraries, ";");
@@ -6037,7 +6115,7 @@ void cmGeneratorTarget::ComputeLinkInterfaceLibraries(
const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
const std::string& config, cmGeneratorTarget const* headTarget,
- bool usage_requirements_only) const
+ bool usage_requirements_only, bool secondPass) const
{
cmGeneratorTarget::ImportInfo const* info = this->GetImportInfo(config);
if (!info) {
@@ -6050,6 +6128,10 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
? this->GetHeadToLinkInterfaceUsageRequirementsMap(config)
: this->GetHeadToLinkInterfaceMap(config));
+ if (secondPass) {
+ hm.erase(headTarget);
+ }
+
// If the link interface does not depend on the head target
// then return the one we computed first.
if (!hm.empty() && !hm.begin()->second.HadHeadSensitiveCondition) {
@@ -6063,7 +6145,8 @@ const cmLinkInterface* cmGeneratorTarget::GetImportLinkInterface(
cmExpandList(info->Languages, iface.Languages);
this->ExpandLinkItems(info->LibrariesProp, info->Libraries, config,
headTarget, usage_requirements_only, iface.Libraries,
- iface.HadHeadSensitiveCondition);
+ iface.HadHeadSensitiveCondition,
+ iface.HadLinkLanguageSensitiveCondition);
std::vector<std::string> deps = cmExpandedList(info->SharedDeps);
this->LookupLinkItems(deps, cmListFileBacktrace(), iface.SharedDeps);
}
@@ -6268,6 +6351,12 @@ cmGeneratorTarget::GetHeadToLinkInterfaceUsageRequirementsMap(
const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
const std::string& config) const
{
+ return this->GetLinkImplementation(config, false);
+}
+
+const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
+ const std::string& config, bool secondPass) const
+{
// There is no link implementation for imported targets.
if (this->IsImported()) {
return nullptr;
@@ -6275,6 +6364,9 @@ const cmLinkImplementation* cmGeneratorTarget::GetLinkImplementation(
std::string CONFIG = cmSystemTools::UpperCase(config);
cmOptionalLinkImplementation& impl = this->LinkImplMap[CONFIG][this];
+ if (secondPass) {
+ impl = cmOptionalLinkImplementation();
+ }
if (!impl.LibrariesDone) {
impl.LibrariesDone = true;
this->ComputeLinkImplementationLibraries(config, impl, this);
@@ -6572,11 +6664,15 @@ void cmGeneratorTarget::ComputeLinkImplementationLibraries(
cmGeneratorExpression ge(*btIt);
std::unique_ptr<cmCompiledGeneratorExpression> const cge = ge.Parse(*le);
std::string const& evaluated =
- cge->Evaluate(this->LocalGenerator, config, head, &dagChecker);
+ cge->Evaluate(this->LocalGenerator, config, head, &dagChecker, nullptr,
+ this->LinkerLanguage);
cmExpandList(evaluated, llibs);
if (cge->GetHadHeadSensitiveCondition()) {
impl.HadHeadSensitiveCondition = true;
}
+ if (cge->GetHadLinkLanguageSensitiveCondition()) {
+ impl.HadLinkLanguageSensitiveCondition = true;
+ }
for (std::string const& lib : llibs) {
if (this->IsLinkLookupScope(lib, lg)) {
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index d81bb3d..9f90cec 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -357,7 +357,6 @@ public:
};
LinkClosure const* GetLinkClosure(const std::string& config) const;
- void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
cmLinkImplementation const* GetLinkImplementation(
const std::string& config) const;
@@ -816,6 +815,7 @@ private:
std::string& outPrefix, std::string& outBase,
std::string& outSuffix) const;
+ mutable std::string LinkerLanguage;
using LinkClosureMapType = std::map<std::string, LinkClosure>;
mutable LinkClosureMapType LinkClosureMap;
@@ -850,6 +850,10 @@ private:
void CheckPropertyCompatibility(cmComputeLinkInformation& info,
const std::string& config) const;
+ void ComputeLinkClosure(const std::string& config, LinkClosure& lc) const;
+ bool ComputeLinkClosure(const std::string& config, LinkClosure& lc,
+ bool secondPass) const;
+
struct LinkImplClosure : public std::vector<cmGeneratorTarget const*>
{
bool Done = false;
@@ -868,6 +872,17 @@ private:
std::string GetLinkInterfaceDependentStringAsBoolProperty(
const std::string& p, const std::string& config) const;
+ friend class cmTargetCollectLinkLanguages;
+ cmLinkInterface const* GetLinkInterface(const std::string& config,
+ const cmGeneratorTarget* headTarget,
+ bool secondPass) const;
+ void ComputeLinkInterface(const std::string& config,
+ cmOptionalLinkInterface& iface,
+ const cmGeneratorTarget* head,
+ bool secondPass) const;
+ cmLinkImplementation const* GetLinkImplementation(const std::string& config,
+ bool secondPass) const;
+
// Cache import information from properties for each configuration.
struct ImportInfo
{
@@ -894,9 +909,10 @@ private:
the link dependencies of this target. */
std::string CheckCMP0004(std::string const& item) const;
- cmLinkInterface const* GetImportLinkInterface(
- const std::string& config, const cmGeneratorTarget* head,
- bool usage_requirements_only) const;
+ cmLinkInterface const* GetImportLinkInterface(const std::string& config,
+ const cmGeneratorTarget* head,
+ bool usage_requirements_only,
+ bool secondPass = false) const;
using KindedSourcesMapType = std::map<std::string, KindedSources>;
mutable KindedSourcesMapType KindedSourcesMap;
@@ -940,7 +956,8 @@ private:
const cmGeneratorTarget* headTarget,
bool usage_requirements_only,
std::vector<cmLinkItem>& items,
- bool& hadHeadSensitiveCondition) const;
+ bool& hadHeadSensitiveCondition,
+ bool& hadLinkLanguageSensitiveCondition) const;
void LookupLinkItems(std::vector<std::string> const& names,
cmListFileBacktrace const& bt,
std::vector<cmLinkItem>& items) const;
diff --git a/Source/cmLinkItem.h b/Source/cmLinkItem.h
index 0ea25c0..ae87e45 100644
--- a/Source/cmLinkItem.h
+++ b/Source/cmLinkItem.h
@@ -81,6 +81,9 @@ struct cmLinkInterface : public cmLinkInterfaceLibraries
std::vector<cmLinkItem> WrongConfigLibraries;
bool ImplementationIsInterface = false;
+
+ // Whether the list depends on a link language genex.
+ bool HadLinkLanguageSensitiveCondition = false;
};
struct cmOptionalLinkInterface : public cmLinkInterface
@@ -100,6 +103,9 @@ struct cmLinkImplementation : public cmLinkImplementationLibraries
{
// Languages whose runtime libraries must be linked.
std::vector<std::string> Languages;
+
+ // Whether the list depends on a link language genex.
+ bool HadLinkLanguageSensitiveCondition = false;
};
// Cache link implementation computation from each configuration.
diff --git a/Tests/BuildDepends/CMakeLists.txt b/Tests/BuildDepends/CMakeLists.txt
index c1ad17c..5ddae83 100644
--- a/Tests/BuildDepends/CMakeLists.txt
+++ b/Tests/BuildDepends/CMakeLists.txt
@@ -368,6 +368,28 @@ is not newer than dependency
${TEST_LINK_DEPENDS}
")
endif()
+
+ set(linkdep3 ${BuildDepends_BINARY_DIR}/Project/linkdep3${CMAKE_EXECUTABLE_SUFFIX})
+ if(${linkdep3} IS_NEWER_THAN ${TEST_LINK_DEPENDS})
+ message("$<LINK_LANGUAGE> in LINK_DEPENDS worked")
+ else()
+ message(SEND_ERROR "$<LINK_LANGUAGE> in LINK_DEPENDS failed. Executable
+ ${linkdep3}
+is not newer than dependency
+ ${TEST_LINK_DEPENDS}
+")
+ endif()
+
+ set(linkdep4 ${BuildDepends_BINARY_DIR}/Project/linkdep4${CMAKE_EXECUTABLE_SUFFIX})
+ if(${linkdep4} IS_NEWER_THAN ${TEST_LINK_DEPENDS})
+ message("$<LINK_LANGUAGE> in INTERFACE_LINK_DEPENDS worked")
+ else()
+ message(SEND_ERROR "$<LINK_LANGUAGE> in INTERFACE_LINK_DEPENDS failed. Executable
+ ${linkdep4}
+is not newer than dependency
+ ${TEST_LINK_DEPENDS}
+")
+ endif()
endif()
if(EXISTS "${link_depends_no_shared_check_txt}")
diff --git a/Tests/BuildDepends/Project/CMakeLists.txt b/Tests/BuildDepends/Project/CMakeLists.txt
index 8338800..83583c9 100644
--- a/Tests/BuildDepends/Project/CMakeLists.txt
+++ b/Tests/BuildDepends/Project/CMakeLists.txt
@@ -118,6 +118,14 @@ if(TEST_LINK_DEPENDS)
set_property(TARGET foo_interface PROPERTY INTERFACE_LINK_DEPENDS $<1:${TEST_LINK_DEPENDS}>)
add_executable(linkdep2 linkdep.cxx)
target_link_libraries(linkdep2 PRIVATE foo_interface)
+
+ add_executable(linkdep3 linkdep.cxx)
+ set_property(TARGET linkdep3 PROPERTY LINK_DEPENDS $<$<LINK_LANGUAGE:CXX>:${TEST_LINK_DEPENDS}>)
+
+ add_library(foo_interface2 INTERFACE)
+ set_property(TARGET foo_interface2 PROPERTY INTERFACE_LINK_DEPENDS $<$<LINK_LANGUAGE:CXX>:${TEST_LINK_DEPENDS}>)
+ add_executable(linkdep4 linkdep.cxx)
+ target_link_libraries(linkdep4 PRIVATE foo_interface2)
endif()
add_library(link_depends_no_shared_lib SHARED link_depends_no_shared_lib.c
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-stderr.txt
new file mode 100644
index 0000000..0b0d458
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_custom_command.cmake:2 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command.cmake
new file mode 100644
index 0000000..a378c1c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-stderr.txt
new file mode 100644
index 0000000..92da634
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_custom_target.cmake:1 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target.cmake
new file mode 100644
index 0000000..60b6c75
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_target.cmake
@@ -0,0 +1,3 @@
+add_custom_target(drive
+ COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-stderr.txt
new file mode 100644
index 0000000..3bdc8e4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_executable.cmake:1 \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable.cmake
new file mode 100644
index 0000000..2176b39
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_executable.cmake
@@ -0,0 +1 @@
+add_executable(empty empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-stderr.txt
new file mode 100644
index 0000000..1bacdeb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_library.cmake:1 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library.cmake
new file mode 100644
index 0000000..253f82a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_library.cmake
@@ -0,0 +1 @@
+add_library(empty empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-stderr.txt
new file mode 100644
index 0000000..f22efde
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-add_test.cmake:5 \(add_test\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test.cmake
new file mode 100644
index 0000000..4fd547d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-stderr.txt
new file mode 100644
index 0000000..21d26de
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-file_generate.cmake:3 \(file\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate.cmake
new file mode 100644
index 0000000..519b883
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-file_generate.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX C)
+
+file(GENERATE
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.txt
+ CONTENT "LANG_IS_$<LINK_LANGUAGE>\n"
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-stderr.txt
new file mode 100644
index 0000000..73afc33
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+
+
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install.cmake
new file mode 100644
index 0000000..533c0b4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ empty.$<LINK_LANGUAGE>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-stderr.txt
new file mode 100644
index 0000000..d8121cc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-target_sources.cmake:2 \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources.cmake
new file mode 100644
index 0000000..c134c01
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE empty.$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-unknown-lang.cmake
new file mode 100644
index 0000000..0ba472d
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_link_options(empty PRIVATE $<$<LINK_LANGUAGE:CXX>:$<TARGET_EXISTS:too,many,parameters>>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-stderr.txt
new file mode 100644
index 0000000..1e3a83b
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage1.cmake:4 \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE:C>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1.cmake
new file mode 100644
index 0000000..90b7ce0
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage1.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<$<LINK_LANGUAGE:C>:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-stderr.txt
new file mode 100644
index 0000000..7fe4310
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage2.cmake:4 \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE:C>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2.cmake
new file mode 100644
index 0000000..e761897
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage2.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<LINK_LANGUAGE:C>:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-stderr.txt
new file mode 100644
index 0000000..cb20e99
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANGUAGE-wrong-usage3.cmake:4 \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE:C>
+
+ \$<LINK_LANGUAGE:...> may only be used with binary targets to specify link
+ libraries, link directories, link options and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3.cmake
new file mode 100644
index 0000000..96a72a1
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage3.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<$<LINK_LANGUAGE:C>:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-stderr.txt
new file mode 100644
index 0000000..ee36912
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at LINK_LANGUAGE-wrong-usage4.cmake:7 \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE> is not supported in link libraries expression.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4.cmake
new file mode 100644
index 0000000..3ecaabb
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-wrong-usage4.cmake
@@ -0,0 +1,7 @@
+
+enable_language(C)
+
+add_library(libC empty.c)
+
+add_executable(empty empty.c)
+target_link_libraries(empty PRIVATE lib$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-stderr.txt
new file mode 100644
index 0000000..2ff62bc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_custom_command.cmake:2 \(add_custom_command\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:LANG,ID>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command.cmake
new file mode 100644
index 0000000..9df9232
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_command.cmake
@@ -0,0 +1,4 @@
+add_custom_target(drive)
+add_custom_command(TARGET drive PRE_BUILD
+ COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:LANG,ID>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-stderr.txt
new file mode 100644
index 0000000..0749c44
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_custom_target.cmake:2 \(add_custom_target\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:LANG,ID>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target.cmake
new file mode 100644
index 0000000..e5f76bc
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_custom_target.cmake
@@ -0,0 +1,4 @@
+
+add_custom_target(drive
+ COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:LANG,ID>
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-stderr.txt
new file mode 100644
index 0000000..595312a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_executable.cmake:1 \(add_executable\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,MSVC>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable.cmake
new file mode 100644
index 0000000..4d6c674
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_executable.cmake
@@ -0,0 +1,5 @@
+add_executable(empty main.c
+ $<$<LINK_LANG_AND_ID:C,MSVC>:empty.c>
+ $<$<LINK_LANG_AND_ID:C,GNU>:empty2.c>
+ $<$<LINK_LANG_AND_ID:C,Clang>:empty3.c>
+ )
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-stderr.txt
new file mode 100644
index 0000000..be46e28
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_library.cmake:2 \(add_library\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,MSVC>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library.cmake
new file mode 100644
index 0000000..a8199cf
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_library.cmake
@@ -0,0 +1,2 @@
+
+add_library(empty empty.$<LINK_LANG_AND_ID:C,MSVC>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-stderr.txt
new file mode 100644
index 0000000..2a29492
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-add_test.cmake:5 \(add_test\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:CXX,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test.cmake
new file mode 100644
index 0000000..fd700d7
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-add_test.cmake
@@ -0,0 +1,5 @@
+
+include(CTest)
+enable_testing()
+
+add_test(NAME dummy COMMAND ${CMAKE_COMMAND} -E echo $<LINK_LANG_AND_ID:CXX,GNU>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-stderr.txt
new file mode 100644
index 0000000..e57b55c
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-file_generate.cmake:3 \(file\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate.cmake
new file mode 100644
index 0000000..67c1bda
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-file_generate.cmake
@@ -0,0 +1,6 @@
+enable_language(CXX C)
+
+file(GENERATE
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.txt
+ CONTENT "LANG_IS_$<$<LINK_LANG_AND_ID:C,GNU>:C>\n"
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-stderr.txt
new file mode 100644
index 0000000..965f974
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install-stderr.txt
@@ -0,0 +1,10 @@
+CMake Error:
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,MSVC>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+
+
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install.cmake
new file mode 100644
index 0000000..b8f9323
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-install.cmake
@@ -0,0 +1,5 @@
+
+install(FILES
+ empty.$<LINK_LANG_AND_ID:C,MSVC>
+ DESTINATION src
+)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-stderr.txt
new file mode 100644
index 0000000..e86602a
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at LINK_LANG_AND_ID-target_sources.cmake:2 \(target_sources\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID>
+
+ \$<LINK_LANG_AND_ID> expression requires at least two parameters.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources.cmake
new file mode 100644
index 0000000..da5faf4
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-target_sources.cmake
@@ -0,0 +1,2 @@
+add_library(empty)
+target_sources(empty PRIVATE empty.$<LINK_LANG_AND_ID>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-unknown-lang.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-unknown-lang.cmake
new file mode 100644
index 0000000..99dd337
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-unknown-lang.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_link_options(empty PRIVATE $<$<LINK_LANG_AND_ID:CXX,GNU>:$<TARGET_EXISTS:too,many,parameters>>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-stderr.txt
new file mode 100644
index 0000000..95611c3
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage1.cmake:4 \(target_compile_definitions\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1.cmake
new file mode 100644
index 0000000..e58e3b44
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage1.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_definitions(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:DEF>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-stderr.txt
new file mode 100644
index 0000000..53bdcb2
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage2.cmake:4 \(target_compile_options\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2.cmake
new file mode 100644
index 0000000..998daa9
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage2.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_compile_options(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:-OPT>)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-stderr.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-stderr.txt
new file mode 100644
index 0000000..a34a2ea
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at LINK_LANG_AND_ID-wrong-usage3.cmake:4 \(target_include_directories\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANG_AND_ID:C,GNU>
+
+ \$<LINK_LANG_AND_ID:lang,id> may only be used with binary targets to specify
+ link libraries, link directories, link options, and link depends.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3.cmake b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3.cmake
new file mode 100644
index 0000000..0543056
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANG_AND_ID-wrong-usage3.cmake
@@ -0,0 +1,4 @@
+
+enable_language(C)
+add_executable(empty empty.c)
+target_include_directories(empty PRIVATE $<$<LINK_LANG_AND_ID:C,GNU>:/DIR>)
diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
index 68a0172..6550f84 100644
--- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
+++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake
@@ -39,6 +39,31 @@ 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(LINK_LANGUAGE-add_custom_target)
+run_cmake(LINK_LANGUAGE-add_custom_command)
+run_cmake(LINK_LANGUAGE-install)
+run_cmake(LINK_LANGUAGE-target_sources)
+run_cmake(LINK_LANGUAGE-add_executable)
+run_cmake(LINK_LANGUAGE-add_library)
+run_cmake(LINK_LANGUAGE-add_test)
+run_cmake(LINK_LANGUAGE-unknown-lang)
+run_cmake(LINK_LANGUAGE-wrong-usage1)
+run_cmake(LINK_LANGUAGE-wrong-usage2)
+run_cmake(LINK_LANGUAGE-wrong-usage3)
+run_cmake(LINK_LANGUAGE-wrong-usage4)
+run_cmake(LINK_LANGUAGE-file_generate)
+run_cmake(LINK_LANG_AND_ID-add_custom_target)
+run_cmake(LINK_LANG_AND_ID-add_custom_command)
+run_cmake(LINK_LANG_AND_ID-install)
+run_cmake(LINK_LANG_AND_ID-target_sources)
+run_cmake(LINK_LANG_AND_ID-add_executable)
+run_cmake(LINK_LANG_AND_ID-add_library)
+run_cmake(LINK_LANG_AND_ID-add_test)
+run_cmake(LINK_LANG_AND_ID-unknown-lang)
+run_cmake(LINK_LANG_AND_ID-wrong-usage1)
+run_cmake(LINK_LANG_AND_ID-wrong-usage2)
+run_cmake(LINK_LANG_AND_ID-wrong-usage3)
+run_cmake(LINK_LANG_AND_ID-file_generate)
run_cmake(TARGET_FILE-recursion)
run_cmake(OUTPUT_NAME-recursion)
run_cmake(TARGET_FILE_PREFIX)
diff --git a/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt
index 03c002e..7abf76a 100644
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-stderr.txt
+++ b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at LINK_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\):
+CMake Error at LINKER_LANGUAGE-genex.cmake:[0-9]+ \(target_link_libraries\):
Error evaluating generator expression:
\$<TARGET_PROPERTY:LINKER_LANGUAGE>
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex.cmake
index 64f394c..64f394c 100644
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex.cmake
+++ b/Tests/RunCMake/Languages/LINKER_LANGUAGE-genex.cmake
diff --git a/Tests/RunCMake/Languages/RunCMakeTest.cmake b/Tests/RunCMake/Languages/RunCMakeTest.cmake
index 2a534b3..48216e9 100644
--- a/Tests/RunCMake/Languages/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Languages/RunCMakeTest.cmake
@@ -1,7 +1,7 @@
include(RunCMake)
run_cmake(NoLangSHARED)
-run_cmake(LINK_LANGUAGE-genex)
+run_cmake(LINKER_LANGUAGE-genex)
run_cmake(link-libraries-TARGET_FILE-genex)
run_cmake(link-libraries-TARGET_FILE-genex-ok)
diff --git a/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake b/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake
new file mode 100644
index 0000000..cc4ce4c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/GENEX_LINK_LANG.cmake
@@ -0,0 +1,16 @@
+
+enable_language(C)
+
+set(obj "${CMAKE_C_OUTPUT_EXTENSION}")
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANGUAGE:C>:${pre}BADFLAG_LANG_C${obj}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_LANG_CXX${obj}>)
+
+add_library(LinkOptions_shared SHARED LinkOptionsLib.c)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake b/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
index bebd6c7..ece3ba0 100644
--- a/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
+++ b/Tests/RunCMake/add_link_options/LINKER_expansion-validation.cmake
@@ -11,5 +11,8 @@ endif()
file(READ "${RunCMake_TEST_BINARY_DIR}/LINKER.txt" linker_flag)
if (NOT actual_stdout MATCHES "${linker_flag}")
- set (RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "LINKER: was not expanded correctly.")
endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
index 4a22d7e..127a2f5 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-exe-check.cmake
@@ -3,5 +3,8 @@ if (NOT actual_stdout MATCHES "BADFLAG_EXECUTABLE_RELEASE")
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_EXECUTABLE_RELEASE'.")
endif()
if (actual_stdout MATCHES "BADFLAG_(SHARED|MODULE)_RELEASE")
- set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|MODULE)_RELEASE'.")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|MODULE)_RELEASE'.")
endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
index d695761..874e0ad 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-mod-check.cmake
@@ -3,5 +3,8 @@ if (NOT actual_stdout MATCHES "BADFLAG_MODULE_RELEASE")
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_MODULE_RELEASE'.")
endif()
if (actual_stdout MATCHES "BADFLAG_(SHARED|EXECUTABLE)_RELEASE")
- set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|EXECUTABLE)_RELEASE'.")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(SHARED|EXECUTABLE)_RELEASE'.")
endif()
diff --git a/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
index eaac8e3..ecba17e 100644
--- a/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
+++ b/Tests/RunCMake/add_link_options/LINK_OPTIONS-shared-check.cmake
@@ -3,5 +3,8 @@ if (NOT actual_stdout MATCHES "BADFLAG_SHARED_RELEASE")
set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_SHARED_RELEASE'.")
endif()
if (actual_stdout MATCHES "BADFLAG_(MODULE|EXECUTABLE)_RELEASE")
- set (RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(MODULE|EXECUTABLE)_RELEASE'.")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(MODULE|EXECUTABLE)_RELEASE'.")
endif()
diff --git a/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx b/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx
new file mode 100644
index 0000000..9bbd24c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/LinkOptionsLib.cxx
@@ -0,0 +1,7 @@
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ int flags_lib(void)
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
index 4f5df72..465ff85 100644
--- a/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
+++ b/Tests/RunCMake/add_link_options/RunCMakeTest.cmake
@@ -23,6 +23,21 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release)
run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release)
+
+ run_cmake(genex_LINK_LANGUAGE)
+
+ run_cmake_target(genex_LINK_LANGUAGE shared_c LinkOptions_shared_c --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE shared_cxx LinkOptions_shared_cxx --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE mod LinkOptions_mod --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE exe LinkOptions_exe --config Release)
+
+ run_cmake(genex_LINK_LANG_AND_ID)
+
+ run_cmake_target(genex_LINK_LANG_AND_ID shared_c LinkOptions_shared_c --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID shared_cxx LinkOptions_shared_cxx --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID mod LinkOptions_mod --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID exe LinkOptions_exe --config Release)
+
unset(RunCMake_TEST_OPTIONS)
unset(RunCMake_TEST_OUTPUT_MERGE)
endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
new file mode 100644
index 0000000..ba0120c
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake
new file mode 100644
index 0000000..aa39810
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-shared_cxx-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake
new file mode 100644
index 0000000..f0237ab
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE-validation.cmake
@@ -0,0 +1,17 @@
+
+if (NOT DEFINED VALID_LANG)
+ set (VALID_LANG C)
+endif()
+if (NOT DEFINED INVALID_LANG)
+ set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG")
+ set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG'.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG'.")
+endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake
new file mode 100644
index 0000000..d74d448
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANGUAGE.cmake
@@ -0,0 +1,17 @@
+
+enable_language(C)
+enable_language(CXX)
+
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.cxx)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
new file mode 100644
index 0000000..cf498d9
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake
new file mode 100644
index 0000000..ed4f851
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-shared_cxx-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake
new file mode 100644
index 0000000..a5dc27f
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID-validation.cmake
@@ -0,0 +1,23 @@
+
+if (NOT VALID_LANG)
+ set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+ set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG_ID")
+ set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG_ID'.\n")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG_ID")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG_ID '.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID'.")
+endif()
diff --git a/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake
new file mode 100644
index 0000000..c807050
--- /dev/null
+++ b/Tests/RunCMake/add_link_options/genex_LINK_LANG_AND_ID.cmake
@@ -0,0 +1,19 @@
+
+enable_language(C)
+enable_language(CXX)
+
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_link_options ($<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.cxx)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
diff --git a/Tests/RunCMake/target_link_directories/CMP0099.cmake b/Tests/RunCMake/target_link_directories/CMP0099.cmake
index a2be279..aff1e33 100644
--- a/Tests/RunCMake/target_link_directories/CMP0099.cmake
+++ b/Tests/RunCMake/target_link_directories/CMP0099.cmake
@@ -5,7 +5,7 @@ set(CMAKE_VERBOSE_MAKEFILE TRUE)
set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
add_library(LinkDirs_interface INTERFACE)
-target_link_directories (LinkDirs_interface INTERFACE "/DIR_INTERFACE"})
+target_link_directories (LinkDirs_interface INTERFACE "/DIR_INTERFACE")
add_library(LinkDirs_static STATIC lib.c)
target_link_libraries (LinkDirs_static PRIVATE LinkDirs_interface)
diff --git a/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake b/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake
index a74ee25..699e871 100644
--- a/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_directories/RunCMakeTest.cmake
@@ -21,10 +21,21 @@ if(RunCMake_GENERATOR MATCHES "(Ninja|Makefiles)" AND
set(VERBOSE -- -v)
endif()
+ run_cmake(genex_LINK_LANGUAGE)
+ run_cmake_target(genex_LINK_LANGUAGE interface LinkDirs_exe_interface --config Release ${VERBOSE})
+ run_cmake_target(genex_LINK_LANGUAGE basic LinkDirs_exe_c --config Release ${VERBOSE})
+ run_cmake_target(genex_LINK_LANGUAGE LINKER_LANGUAGE LinkDirs_exe_cxx --config Release ${VERBOSE})
+
+ run_cmake(genex_LINK_LANG_AND_ID)
+
+ run_cmake_target(genex_LINK_LANG_AND_ID interface LinkDirs_exe_interface --config Release ${VERBOSE})
+ run_cmake_target(genex_LINK_LANG_AND_ID basic LinkDirs_exe_c --config Release ${VERBOSE})
+ run_cmake_target(genex_LINK_LANG_AND_ID LINKER_LANGUAGE LinkDirs_exe_cxx --config Release ${VERBOSE})
+
+
run_cmake(CMP0099-NEW)
run_cmake_target(CMP0099-NEW basic LinkDirs_exe ${VERBOSE})
-
run_cmake(CMP0099-OLD)
run_cmake_target(CMP0099-OLD basic LinkDirs_exe ${VERBOSE})
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake
new file mode 100644
index 0000000..aa39810
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-basic-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-check.cmake
new file mode 100644
index 0000000..8313de6
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-check.cmake
@@ -0,0 +1,4 @@
+
+set (TYPE INTERFACE)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-validation.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-validation.cmake
new file mode 100644
index 0000000..298564e
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE-validation.cmake
@@ -0,0 +1,20 @@
+
+if (NOT VALID_LANG)
+ set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+ set (INVALID_LANG CXX)
+endif()
+if (NOT TYPE)
+ set (TYPE EXE)
+endif()
+
+if (NOT actual_stdout MATCHES "DIR_${VALID_LANG}_${TYPE}")
+ set (RunCMake_TEST_FAILED "Not found expected 'DIR_${VALID_LANG}_${TYPE}'.")
+endif()
+if (actual_stdout MATCHES "DIR_${INVALID_LANG}_${TYPE}")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'DIR_${INVALID_LANG}_${TYPE}'.")
+endif()
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE.cmake
new file mode 100644
index 0000000..1f266b1
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANGUAGE.cmake
@@ -0,0 +1,23 @@
+
+enable_language(C)
+enable_language(CXX)
+
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+
+add_library(LinkDirs_interface INTERFACE)
+target_link_directories (LinkDirs_interface INTERFACE "$<$<LINK_LANGUAGE:C>:/DIR_C_INTERFACE>"
+ "$<$<LINK_LANGUAGE:CXX>:/DIR_CXX_INTERFACE>")
+
+add_executable(LinkDirs_exe_interface exe.c)
+target_link_libraries (LinkDirs_exe_interface PRIVATE LinkDirs_interface)
+
+add_executable(LinkDirs_exe_c exe.c)
+target_link_directories (LinkDirs_exe_c PRIVATE "$<$<LINK_LANGUAGE:C>:/DIR_C_EXE>"
+ "$<$<LINK_LANGUAGE:CXX>:/DIR_CXX_EXE>")
+
+add_executable(LinkDirs_exe_cxx exe.c)
+target_link_directories (LinkDirs_exe_cxx PRIVATE "$<$<LINK_LANGUAGE:C>:/DIR_C_EXE>"
+ "$<$<LINK_LANGUAGE:CXX>:/DIR_CXX_EXE>")
+set_property (TARGET LinkDirs_exe_cxx PROPERTY LINKER_LANGUAGE CXX)
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake
new file mode 100644
index 0000000..ed4f851
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-basic-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-check.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-check.cmake
new file mode 100644
index 0000000..a328738
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-check.cmake
@@ -0,0 +1,4 @@
+
+set (TYPE INTERFACE)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-result.txt b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-validation.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-validation.cmake
new file mode 100644
index 0000000..9872953
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID-validation.cmake
@@ -0,0 +1,26 @@
+
+if (NOT VALID_LANG)
+ set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+ set (INVALID_LANG CXX)
+endif()
+if (NOT TYPE)
+ set (TYPE EXE)
+endif()
+
+if (NOT actual_stdout MATCHES "DIR_${VALID_LANG}_${TYPE}")
+ set (RunCMake_TEST_FAILED "Not found expected 'DIR_${VALID_LANG}_${TYPE}'.\n")
+endif()
+if (actual_stdout MATCHES "DIR_${INVALID_LANG}_${TYPE}")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'DIR_${INVALID_LANG}_${TYPE} '.")
+endif()
+if (actual_stdout MATCHES "DIR_(${VALID_LANG}|${INVALID_LANG})_BADID_${TYPE}")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'DIR_(${VALID_LANG}|${INVALID_LANG})_BADID_${TYPE}'.")
+endif()
diff --git a/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID.cmake b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID.cmake
new file mode 100644
index 0000000..eb3b342
--- /dev/null
+++ b/Tests/RunCMake/target_link_directories/genex_LINK_LANG_AND_ID.cmake
@@ -0,0 +1,29 @@
+
+enable_language(C)
+enable_language(CXX)
+
+set(CMAKE_VERBOSE_MAKEFILE TRUE)
+set(CMAKE_C_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_LIBRARIES FALSE)
+
+add_library(LinkDirs_interface INTERFACE)
+target_link_directories (LinkDirs_interface INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:/DIR_C_INTERFACE>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:/DIR_CXX_INTERFACE>
+ $<$<LINK_LANG_AND_ID:C,BADID>:/DIR_C_BADID_INTERFACE>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:/DIR_CXX_BADID_INTERFACE>)
+
+add_executable(LinkDirs_exe_interface exe.c)
+target_link_libraries (LinkDirs_exe_interface PRIVATE LinkDirs_interface)
+
+add_executable(LinkDirs_exe_c exe.c)
+target_link_options (LinkDirs_exe_c PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:/DIR_C_EXE>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:/DIR_CXX_EXE>
+ $<$<LINK_LANG_AND_ID:C,BADID>:/DIR_C_BADID_EXE>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:/DIR_CXX_BADID_EXE>)
+
+add_executable(LinkDirs_exe_cxx exe.c)
+target_link_directories (LinkDirs_exe_cxx PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:/DIR_C_EXE>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:/DIR_CXX_EXE>
+ $<$<LINK_LANG_AND_ID:C,BADID>:/DIR_C_BADID_EXE>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:/DIR_CXX_BADID_EXE>)
+set_property (TARGET LinkDirs_exe_cxx PROPERTY LINKER_LANGUAGE CXX)
diff --git a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
index 0152d4c..c7feb5f 100644
--- a/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_libraries/RunCMakeTest.cmake
@@ -20,3 +20,57 @@ run_cmake(StaticPrivateDepNotExported)
run_cmake(StaticPrivateDepNotTarget)
run_cmake(UNKNOWN-IMPORTED-GLOBAL)
run_cmake(empty_keyword_args)
+run_cmake(genex_LINK_LANGUAGE-bad-usage)
+
+if (RunCMake_GENERATOR MATCHES "Makefiles|Ninja|Visual Studio|Xcode|Watcom WMake")
+
+ run_cmake(genex_LINK_LANGUAGE-bad-mix-lang)
+ run_cmake(genex_LINK_LANG_AND_ID-bad-mix-lang)
+
+ macro(run_cmake_target test subtest target)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${test}-build)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command(${test}-${subtest} ${CMAKE_COMMAND} --build . --target ${target} ${ARGN})
+
+ unset(RunCMake_TEST_BINARY_DIR)
+ unset(RunCMake_TEST_NO_CLEAN)
+ endmacro()
+
+ set(RunCMake_TEST_OUTPUT_MERGE TRUE)
+ if (NOT RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Release)
+ endif()
+
+ run_cmake(genex_LINK_LANGUAGE)
+
+ run_cmake_target(genex_LINK_LANGUAGE lib LinkLibraries_lib --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE lib2 LinkLibraries_lib2 --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE lib3 LinkLibraries_lib3 --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE exe LinkLibraries_exe --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE C_import LinkLibraries_C_import --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE CXX_import LinkLibraries_CXX_import --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE C_interface LinkLibraries_C_interface --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE CXX_interface LinkLibraries_CXX_interface --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE C_interface2 LinkLibraries_C_interface2 --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE CXX_interface2 LinkLibraries_CXX_interface2 --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE C_static LinkLibraries_C_static --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE CXX_static LinkLibraries_CXX_static --config Release)
+
+ run_cmake(genex_LINK_LANG_AND_ID)
+
+ run_cmake_target(genex_LINK_LANG_AND_ID lib LinkLibraries_lib --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID lib2 LinkLibraries_lib2 --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID lib3 LinkLibraries_lib3 --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID exe LinkLibraries_exe --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID C_import LinkLibraries_C_import --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID CXX_import LinkLibraries_CXX_import --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID C_interface LinkLibraries_C_interface --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID CXX_interface LinkLibraries_CXX_interface --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID C_interface2 LinkLibraries_C_interface2 --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID CXX_interface2 LinkLibraries_CXX_interface2 --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID CXX_static LinkLibraries_CXX_static --config Release)
+
+ unset(RunCMake_TEST_OPTIONS)
+ unset(RunCMake_TEST_OUTPUT_MERGE)
+
+endif()
diff --git a/Tests/RunCMake/target_link_libraries/func.c b/Tests/RunCMake/target_link_libraries/func.c
new file mode 100644
index 0000000..415a9bf
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/func.c
@@ -0,0 +1,7 @@
+
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ void func_c()
+{
+}
diff --git a/Tests/RunCMake/target_link_libraries/func.cxx b/Tests/RunCMake/target_link_libraries/func.cxx
new file mode 100644
index 0000000..a12caca
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/func.cxx
@@ -0,0 +1,7 @@
+
+#if defined(_WIN32)
+__declspec(dllexport)
+#endif
+ void func_cxx()
+{
+}
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-result.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-stderr.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-stderr.txt
new file mode 100644
index 0000000..2ecdc0c
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: Evaluation of \$<LINK_LANGUAGE:...> or \$<LINK_LAND_AND_ID:...> changes
+the linker language for target "LinkLibraries_bad_mix_languages" \(from 'C' to 'CXX'\) which is invalid.
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang.cmake b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang.cmake
new file mode 100644
index 0000000..e8efa75
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-mix-lang.cmake
@@ -0,0 +1,8 @@
+
+enable_language(C)
+enable_language(CXX)
+
+add_library(static_CXX STATIC func.cxx)
+
+add_executable(LinkLibraries_bad_mix_languages main.c)
+target_link_libraries (LinkLibraries_bad_mix_languages PRIVATE $<$<LINK_LANGUAGE:C>:static_CXX>)
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-result.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-stderr.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-stderr.txt
new file mode 100644
index 0000000..469f1fe
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage-stderr.txt
@@ -0,0 +1,8 @@
+CMake Error at genex_LINK_LANGUAGE-bad-usage.cmake:4 \(target_link_libraries\):
+ Error evaluating generator expression:
+
+ \$<LINK_LANGUAGE>
+
+ \$<LINK_LANGUAGE> is not supported in link libraries expression.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage.cmake b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage.cmake
new file mode 100644
index 0000000..81cfb0c
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE-bad-usage.cmake
@@ -0,0 +1,4 @@
+enable_language(C)
+
+add_library(simple SHARED empty.c)
+target_link_libraries(simple PRIVATE lib$<LINK_LANGUAGE>)
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE.cmake b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE.cmake
new file mode 100644
index 0000000..f3fe955
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANGUAGE.cmake
@@ -0,0 +1,72 @@
+
+cmake_minimum_required(VERSION 3.16...3.17)
+
+enable_language(C)
+enable_language(CXX)
+
+add_library(shared_C SHARED func.c)
+add_library(shared_CXX SHARED func.cxx)
+
+
+add_library(static1_C STATIC empty.c)
+target_link_libraries (static1_C INTERFACE $<$<LINK_LANGUAGE:C>:shared_C>)
+
+add_library(static2_C STATIC empty.c)
+target_link_libraries (static2_C PRIVATE $<$<LINK_LANGUAGE:C>:shared_C>)
+
+
+set (binary_dir "${CMAKE_BINARY_DIR}")
+get_property (is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if (is_multi_config)
+ string (APPEND binary_dir "/Release")
+endif()
+add_library(import STATIC IMPORTED)
+set_property(TARGET import PROPERTY IMPORTED_LOCATION "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}static1_C${CMAKE_STATIC_LIBRARY_SUFFIX}")
+target_link_libraries (import INTERFACE $<$<LINK_LANGUAGE:C>:shared_C>)
+target_link_libraries (import INTERFACE $<$<LINK_LANGUAGE:CXX>:shared_CXX>)
+
+
+add_library(interface INTERFACE)
+target_link_libraries (interface INTERFACE $<$<LINK_LANGUAGE:C>:shared_C>
+ $<$<LINK_LANGUAGE:CXX>:shared_CXX>)
+
+
+add_library(interface2 INTERFACE)
+target_link_libraries (interface2 INTERFACE import)
+
+
+add_library(static3 STATIC empty.c)
+target_link_libraries (static3 PRIVATE interface)
+
+
+add_library(LinkLibraries_lib SHARED lib.c)
+target_link_libraries (LinkLibraries_lib PRIVATE $<$<LINK_LANGUAGE:C>:shared_C>)
+
+add_library(LinkLibraries_lib2 SHARED lib.c)
+target_link_libraries (LinkLibraries_lib2 PRIVATE $<$<LINK_LANGUAGE:C>:static1_C>)
+
+add_library(LinkLibraries_lib3 SHARED lib.c)
+target_link_libraries (LinkLibraries_lib3 PRIVATE $<$<LINK_LANGUAGE:C>:static2_C>)
+
+add_executable(LinkLibraries_exe main.c)
+target_link_libraries (LinkLibraries_exe PRIVATE $<$<LINK_LANGUAGE:C>:shared_C>)
+
+add_executable(LinkLibraries_C_import main.c)
+target_link_libraries (LinkLibraries_C_import PRIVATE import)
+add_executable(LinkLibraries_CXX_import main.cxx)
+target_link_libraries (LinkLibraries_CXX_import PRIVATE import)
+
+add_executable(LinkLibraries_C_interface main.c)
+target_link_libraries (LinkLibraries_C_interface PRIVATE interface)
+add_executable(LinkLibraries_CXX_interface main.cxx)
+target_link_libraries (LinkLibraries_CXX_interface PRIVATE interface)
+
+add_executable(LinkLibraries_C_interface2 main.c)
+target_link_libraries (LinkLibraries_C_interface2 PRIVATE interface2)
+add_executable(LinkLibraries_CXX_interface2 main.cxx)
+target_link_libraries (LinkLibraries_CXX_interface2 PRIVATE interface2)
+
+add_executable(LinkLibraries_C_static main.c)
+target_link_libraries (LinkLibraries_C_static PRIVATE static3)
+add_executable(LinkLibraries_CXX_static main.cxx)
+target_link_libraries (LinkLibraries_CXX_static PRIVATE static3)
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-result.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-stderr.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-stderr.txt
new file mode 100644
index 0000000..2ecdc0c
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang-stderr.txt
@@ -0,0 +1,2 @@
+CMake Error: Evaluation of \$<LINK_LANGUAGE:...> or \$<LINK_LAND_AND_ID:...> changes
+the linker language for target "LinkLibraries_bad_mix_languages" \(from 'C' to 'CXX'\) which is invalid.
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang.cmake b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang.cmake
new file mode 100644
index 0000000..f80010a
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-bad-mix-lang.cmake
@@ -0,0 +1,8 @@
+
+enable_language(C)
+enable_language(CXX)
+
+add_library(static_CXX STATIC func.cxx)
+
+add_executable(LinkLibraries_bad_mix_languages main.c)
+target_link_libraries (LinkLibraries_bad_mix_languages PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:static_CXX>)
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-basic-result.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-basic-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-basic-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_c-result.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_cxx-result.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_cxx-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-exe_cxx-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-interface-result.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-no_language-result.txt b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-no_language-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID-no_language-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID.cmake b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID.cmake
new file mode 100644
index 0000000..9feccd0
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/genex_LINK_LANG_AND_ID.cmake
@@ -0,0 +1,73 @@
+
+cmake_minimum_required(VERSION 3.16...3.17)
+
+enable_language(C)
+enable_language(CXX)
+
+
+add_library(shared_C SHARED func.c)
+add_library(shared_CXX SHARED func.cxx)
+
+
+add_library(static1_C STATIC empty.c)
+target_link_libraries (static1_C INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+
+add_library(static2_C STATIC empty.c)
+target_link_libraries (static2_C PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+
+
+set (binary_dir "${CMAKE_BINARY_DIR}")
+get_property (is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+if (is_multi_config)
+ string (APPEND binary_dir "/Release")
+endif()
+add_library(import STATIC IMPORTED)
+set_property(TARGET import PROPERTY IMPORTED_LOCATION "${binary_dir}/${CMAKE_STATIC_LIBRARY_PREFIX}static1_C${CMAKE_STATIC_LIBRARY_SUFFIX}")
+target_link_libraries (import INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+target_link_libraries (import INTERFACE $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:shared_CXX>)
+
+
+add_library(interface INTERFACE)
+target_link_libraries (interface INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:shared_CXX>)
+
+
+add_library(interface2 INTERFACE)
+target_link_libraries (interface2 INTERFACE import)
+
+
+add_library(static3 STATIC empty.c)
+target_link_libraries (static3 PRIVATE interface)
+
+
+add_library(LinkLibraries_lib SHARED lib.c)
+target_link_libraries (LinkLibraries_lib PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+
+add_library(LinkLibraries_lib2 SHARED lib.c)
+target_link_libraries (LinkLibraries_lib2 PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:static1_C>)
+
+add_library(LinkLibraries_lib3 SHARED lib.c)
+target_link_libraries (LinkLibraries_lib3 PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:static2_C>)
+
+add_executable(LinkLibraries_exe main.c)
+target_link_libraries (LinkLibraries_exe PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:shared_C>)
+
+add_executable(LinkLibraries_C_import main.c)
+target_link_libraries (LinkLibraries_C_import PRIVATE import)
+add_executable(LinkLibraries_CXX_import main.cxx)
+target_link_libraries (LinkLibraries_CXX_import PRIVATE import)
+
+add_executable(LinkLibraries_C_interface main.c)
+target_link_libraries (LinkLibraries_C_interface PRIVATE interface)
+add_executable(LinkLibraries_CXX_interface main.cxx)
+target_link_libraries (LinkLibraries_CXX_interface PRIVATE interface)
+
+add_executable(LinkLibraries_C_interface2 main.c)
+target_link_libraries (LinkLibraries_C_interface2 PRIVATE interface2)
+add_executable(LinkLibraries_CXX_interface2 main.cxx)
+target_link_libraries (LinkLibraries_CXX_interface2 PRIVATE interface2)
+
+add_executable(LinkLibraries_C_static main.c)
+target_link_libraries (LinkLibraries_C_static PRIVATE static3)
+add_executable(LinkLibraries_CXX_static main.cxx)
+target_link_libraries (LinkLibraries_CXX_static PRIVATE static3)
diff --git a/Tests/RunCMake/target_link_libraries/lib.c b/Tests/RunCMake/target_link_libraries/lib.c
new file mode 100644
index 0000000..b2d1b66
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/lib.c
@@ -0,0 +1,10 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+ void func_c();
+
+void lib()
+{
+ func_c();
+}
diff --git a/Tests/RunCMake/target_link_libraries/main.c b/Tests/RunCMake/target_link_libraries/main.c
new file mode 100644
index 0000000..a908dea
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/main.c
@@ -0,0 +1,12 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+ void func_c();
+
+int main()
+{
+ func_c();
+
+ return 0;
+}
diff --git a/Tests/RunCMake/target_link_libraries/main.cxx b/Tests/RunCMake/target_link_libraries/main.cxx
new file mode 100644
index 0000000..ffaa3b4
--- /dev/null
+++ b/Tests/RunCMake/target_link_libraries/main.cxx
@@ -0,0 +1,12 @@
+
+#if defined(_WIN32)
+__declspec(dllimport)
+#endif
+ void func_cxx();
+
+int main()
+{
+ func_cxx();
+
+ return 0;
+}
diff --git a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
index cdfdd7b..9fdcdee 100644
--- a/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_link_options/RunCMakeTest.cmake
@@ -27,6 +27,23 @@ if (NOT CMAKE_C_COMPILER_ID STREQUAL "Intel")
run_cmake_target(LINK_OPTIONS mod LinkOptions_mod --config Release)
run_cmake_target(LINK_OPTIONS exe LinkOptions_exe --config Release)
+
+ run_cmake(genex_LINK_LANGUAGE)
+
+ run_cmake_target(genex_LINK_LANGUAGE interface LinkOptions_shared_interface --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE shared_c LinkOptions_shared_c --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE LINKER_LANGUAGE LinkOptions_shared_cxx --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE mod LinkOptions_mod --config Release)
+ run_cmake_target(genex_LINK_LANGUAGE exe LinkOptions_exe --config Release)
+
+ run_cmake(genex_LINK_LANG_AND_ID)
+
+ run_cmake_target(genex_LINK_LANG_AND_ID interface LinkOptions_shared_interface --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID shared_c LinkOptions_shared_c --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID LINKER_LANGUAGE LinkOptions_shared_cxx --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID mod LinkOptions_mod --config Release)
+ run_cmake_target(genex_LINK_LANG_AND_ID exe LinkOptions_exe --config Release)
+
unset(RunCMake_TEST_OPTIONS)
unset(RunCMake_TEST_OUTPUT_MERGE)
endif()
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake
new file mode 100644
index 0000000..aa39810
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-LINKER_LANGUAGE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-check.cmake
new file mode 100644
index 0000000..ba0120c
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-check.cmake
new file mode 100644
index 0000000..71f641d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
new file mode 100644
index 0000000..ba0120c
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANGUAGE-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-validation.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-validation.cmake
new file mode 100644
index 0000000..f0237ab
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE-validation.cmake
@@ -0,0 +1,17 @@
+
+if (NOT DEFINED VALID_LANG)
+ set (VALID_LANG C)
+endif()
+if (NOT DEFINED INVALID_LANG)
+ set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG")
+ set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG'.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG'.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE.cmake
new file mode 100644
index 0000000..61e6159
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANGUAGE.cmake
@@ -0,0 +1,32 @@
+
+enable_language(C)
+enable_language(CXX)
+
+set (obj "${CMAKE_C_OUTPUT_EXTENSION}")
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_library(LinkOptions_interface INTERFACE)
+target_link_options (LinkOptions_interface INTERFACE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
+
+add_library(LinkOptions_shared_interface SHARED LinkOptionsLib.c)
+target_link_libraries (LinkOptions_shared_interface PRIVATE LinkOptions_interface)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_shared_c PRIVATE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
+
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_shared_cxx PRIVATE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
+set_property (TARGET LinkOptions_shared_cxx PROPERTY LINKER_LANGUAGE CXX)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+target_link_options (LinkOptions_mod PRIVATE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
+target_link_options (LinkOptions_exe PRIVATE $<$<LINK_LANGUAGE:C>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>
+ $<$<LINK_LANGUAGE:CXX>:${pre}BADFLAG_$<LINK_LANGUAGE>_LANG${obj}>)
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake
new file mode 100644
index 0000000..ed4f851
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG CXX)
+set (INVALID_LANG C)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-LINKER_LANGUAGE-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-exe-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-check.cmake
new file mode 100644
index 0000000..cf498d9
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-interface-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
new file mode 100644
index 0000000..6bddee1
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-check.cmake
@@ -0,0 +1,2 @@
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-mod-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
new file mode 100644
index 0000000..cf498d9
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-check.cmake
@@ -0,0 +1,5 @@
+
+set (VALID_LANG C)
+set (INVALID_LANG CXX)
+
+include ("${CMAKE_CURRENT_LIST_DIR}/genex_LINK_LANG_AND_ID-validation.cmake")
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-shared_c-result.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-validation.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-validation.cmake
new file mode 100644
index 0000000..a5dc27f
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID-validation.cmake
@@ -0,0 +1,23 @@
+
+if (NOT VALID_LANG)
+ set (VALID_LANG C)
+endif()
+if (NOT INVALID_LANG)
+ set (INVALID_LANG CXX)
+endif()
+
+if (NOT actual_stdout MATCHES "BADFLAG_${VALID_LANG}_LANG_ID")
+ set (RunCMake_TEST_FAILED "Not found expected 'BADFLAG_${VALID_LANG}_LANG_ID'.\n")
+endif()
+if (actual_stdout MATCHES "BADFLAG_${INVALID_LANG}_LANG_ID")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_${INVALID_LANG}_LANG_ID '.")
+endif()
+if (actual_stdout MATCHES "BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID")
+ if (RunCMake_TEST_FAILED)
+ string (APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string (APPEND RunCMake_TEST_FAILED "Found unexpected 'BADFLAG_(${VALID_LANG}|${INVALID_LANG})_BADID'.")
+endif()
diff --git a/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID.cmake b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID.cmake
new file mode 100644
index 0000000..db0f500
--- /dev/null
+++ b/Tests/RunCMake/target_link_options/genex_LINK_LANG_AND_ID.cmake
@@ -0,0 +1,41 @@
+
+enable_language(C)
+enable_language(CXX)
+
+if(BORLAND)
+ set(pre -)
+endif()
+
+add_library(LinkOptions_interface INTERFACE)
+target_link_options (LinkOptions_interface INTERFACE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_interface SHARED LinkOptionsLib.c)
+target_link_libraries (LinkOptions_shared_interface PRIVATE LinkOptions_interface)
+
+add_library(LinkOptions_shared_c SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_shared_c PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_library(LinkOptions_shared_cxx SHARED LinkOptionsLib.c)
+target_link_options (LinkOptions_shared_cxx PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+set_property (TARGET LinkOptions_shared_cxx PROPERTY LINKER_LANGUAGE CXX)
+
+add_library(LinkOptions_mod MODULE LinkOptionsLib.c)
+target_link_options (LinkOptions_mod PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)
+
+add_executable(LinkOptions_exe LinkOptionsExe.c)
+target_link_options (LinkOptions_exe PRIVATE $<$<LINK_LANG_AND_ID:C,${CMAKE_C_COMPILER_ID}>:${pre}BADFLAG_C_LANG_ID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,${CMAKE_CXX_COMPILER_ID}>:${pre}BADFLAG_CXX_LANG_ID${CMAKE_CXX_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:C,BADID>:${pre}BADFLAG_C_BADID${CMAKE_C_OUTPUT_EXTENSION}>
+ $<$<LINK_LANG_AND_ID:CXX,BADID>:${pre}BADFLAG_CXX_BADID${CMAKE_CXX_OUTPUT_EXTENSION}>)