summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/generator/Ninja Multi-Config.rst41
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt12
-rw-r--r--Help/guide/tutorial/index.rst2
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst114
-rw-r--r--Help/manual/cmake-variables.7.rst6
-rw-r--r--Help/release/dev/genex-LINK_LANGUAGE.rst5
-rw-r--r--Help/variable/CMAKE_CROSS_CONFIGS.rst (renamed from Help/variable/CMAKE_NMC_CROSS_CONFIGS.rst)4
-rw-r--r--Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst (renamed from Help/variable/CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG.rst)4
-rw-r--r--Help/variable/CMAKE_DEFAULT_CONFIGS.rst (renamed from Help/variable/CMAKE_NMC_DEFAULT_CONFIGS.rst)4
-rw-r--r--Modules/CMakeGenericSystem.cmake2
-rw-r--r--Modules/CheckFortranSourceCompiles.cmake6
-rw-r--r--Modules/CheckFortranSourceRuns.cmake6
-rw-r--r--Modules/CheckTypeSize.c.in8
-rw-r--r--Modules/Compiler/XL-Fortran.cmake1
-rw-r--r--Modules/FortranCInterface/CMakeLists.txt4
-rw-r--r--Modules/FortranCInterface/Detect.cmake10
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/cmCPluginAPI.cxx34
-rw-r--r--Source/cmCTest.cxx21
-rw-r--r--Source/cmCommandArgumentParserHelper.cxx36
-rw-r--r--Source/cmCommandArgumentParserHelper.h3
-rw-r--r--Source/cmDependsJavaParserHelper.cxx11
-rw-r--r--Source/cmDependsJavaParserHelper.h3
-rw-r--r--Source/cmDynamicLoader.cxx22
-rw-r--r--Source/cmForEachCommand.cxx42
-rw-r--r--Source/cmGeneratedFileStream.cxx1
-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/cmGlobalGenerator.cxx35
-rw-r--r--Source/cmGlobalGenerator.h7
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx30
-rw-r--r--Source/cmGlobalNinjaGenerator.h4
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.cxx13
-rw-r--r--Source/cmGlobalUnixMakefileGenerator3.h9
-rw-r--r--Source/cmInstallExportGenerator.cxx11
-rw-r--r--Source/cmInstallExportGenerator.h7
-rw-r--r--Source/cmLinkItem.h6
-rw-r--r--Source/cmLocalCommonGenerator.cxx9
-rw-r--r--Source/cmMachO.cxx31
-rw-r--r--Source/cmServer.cxx31
-rw-r--r--Source/cmServer.h7
-rw-r--r--Source/cmSourceGroup.cxx11
-rw-r--r--Source/cmSourceGroup.h3
-rw-r--r--Source/cmSystemTools.cxx11
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx129
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h2
-rw-r--r--Tests/BuildDepends/CMakeLists.txt22
-rw-r--r--Tests/BuildDepends/Project/CMakeLists.txt8
-rw-r--r--Tests/CMakeLists.txt21
-rw-r--r--Tests/CSharpOnly/CMakeLists.txt4
-rw-r--r--Tests/CSharpOnly/csharponly.cs4
-rw-r--r--Tests/CSharpOnly/nested/lib1.cs13
-rw-r--r--Tests/FortranModules/CMakeLists.txt2
-rw-r--r--Tests/FortranOnly/CMakeLists.txt50
-rw-r--r--Tests/Preprocess/preprocess.c12
-rw-r--r--Tests/Preprocess/preprocess.cxx15
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt (renamed from Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-result.txt)0
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt11
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake1
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt (renamed from Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt)0
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt11
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake1
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt1
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt11
-rw-r--r--Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake1
-rw-r--r--Tests/RunCMake/Configure/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt1
-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/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt2
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt4
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt2
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt4
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-stderr.txt6
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake42
-rw-r--r--Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs3
-rw-r--r--Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp (renamed from Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile.cmake)0
-rw-r--r--Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs3
-rw-r--r--Tests/RunCMake/VS10Project/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake22
-rw-r--r--Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake16
-rw-r--r--Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake15
-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/foreach/RunCMakeTest.cmake7
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-invalid-test-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-invalid-test-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-invalid-test.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2.cmake2
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-result.txt1
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-stderr.txt4
-rw-r--r--Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3.cmake2
-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
276 files changed, 2214 insertions, 437 deletions
diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst
index 11c59f2..1f68535 100644
--- a/Help/generator/Ninja Multi-Config.rst
+++ b/Help/generator/Ninja Multi-Config.rst
@@ -12,9 +12,10 @@ multiple configurations at once with :variable:`CMAKE_CONFIGURATION_TYPES`
instead of only one configuration with :variable:`CMAKE_BUILD_TYPE`. One
``build-<Config>.ninja`` file will be generated for each of these
configurations (with ``<Config>`` being the configuration name.) These files
-are intended to be run with ``ninja -f build-<Config>.ninja``. No
-``build.ninja`` file is generated by default (see below for how to generate
-it.)
+are intended to be run with ``ninja -f build-<Config>.ninja``. A
+``build.ninja`` file is also generated, using the configuration from either
+:variable:`CMAKE_DEFAULT_BUILD_TYPE` or the first item from
+:variable:`CMAKE_CONFIGURATION_TYPES`.
``cmake --build . --config <Config>`` will always use ``build-<Config>.ninja``
to build. If no ``--config`` argument is specified, ``cmake --build .`` will
@@ -35,7 +36,7 @@ The ``Ninja Multi-Config`` generator recognizes the following variables:
Specifies the total set of configurations to build. See the variable's
documentation for more information.
-:variable:`CMAKE_NMC_CROSS_CONFIGS`
+:variable:`CMAKE_CROSS_CONFIGS`
Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
configurations available from all ``build-<Config>.ninja`` files.
This variable activates cross-config mode.
@@ -49,36 +50,36 @@ The ``Ninja Multi-Config`` generator recognizes the following variables:
The value of this variable must be a subset of
:variable:`CMAKE_CONFIGURATION_TYPES`.
-:variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG`
+:variable:`CMAKE_DEFAULT_BUILD_TYPE`
Specifies the configuration to use by default in a ``build.ninja`` file. If
- this variable is specified, a ``build.ninja`` file is generated which uses
- build rules from ``build-<Config>.ninja`` by default. All custom commands are
- executed with this configuration. If the variable is not specified, no
- ``build.ninja`` file is generated.
+ this variable is specified, ``build.ninja`` uses build rules from
+ ``build-<Config>.ninja`` by default. All custom commands are executed with
+ this configuration. If the variable is not specified, the first item from
+ :variable:`CMAKE_CONFIGURATION_TYPES` is used instead.
The value of this variable must be one of the items from
:variable:`CMAKE_CONFIGURATION_TYPES`.
-:variable:`CMAKE_NMC_DEFAULT_CONFIGS`
+:variable:`CMAKE_DEFAULT_CONFIGS`
Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
configurations to build for a target in ``build.ninja``
if no ``:<Config>`` suffix is specified. If it is set to ``all``, all
- configurations from :variable:`CMAKE_NMC_CROSS_CONFIGS` are used. If
+ configurations from :variable:`CMAKE_CROSS_CONFIGS` are used. If
it is not specified, it defaults to
- :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG`.
+ :variable:`CMAKE_DEFAULT_BUILD_TYPE`.
For example, if you set
- :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG` to ``Release``, but
- set :variable:`CMAKE_NMC_DEFAULT_CONFIGS` to ``Debug`` or ``all``,
+ :variable:`CMAKE_DEFAULT_BUILD_TYPE` to ``Release``, but
+ set :variable:`CMAKE_DEFAULT_CONFIGS` to ``Debug`` or ``all``,
all ``<target>`` aliases in ``build.ninja`` will resolve to
``<target>:Debug`` or ``<target>:all``, but custom commands will still use
the ``Release`` configuration.
The value of this variable must be a subset of
- :variable:`CMAKE_NMC_CROSS_CONFIGS` or be the same as
- :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG`. It must not be
- specified if :variable:`CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG` or
- :variable:`CMAKE_NMC_CROSS_CONFIGS` is not used.
+ :variable:`CMAKE_CROSS_CONFIGS` or be the same as
+ :variable:`CMAKE_DEFAULT_BUILD_TYPE`. It must not be
+ specified if :variable:`CMAKE_DEFAULT_BUILD_TYPE` or
+ :variable:`CMAKE_CROSS_CONFIGS` is not used.
Consider the following example:
@@ -104,8 +105,8 @@ This would build the ``Debug`` configuration of ``generator``, which would be
used to generate ``generated.c``, which would be used to build the ``Debug``
configuration of ``generated``.
-But if :variable:`CMAKE_NMC_CROSS_CONFIGS` is set to ``all``, and you
-run the following instead:
+But if :variable:`CMAKE_CROSS_CONFIGS` is set to ``all``, and you run the
+following instead:
.. code-block:: shell
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index 4bf6024..f64c6ac 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -8,10 +8,20 @@ target_include_directories(MathFunctions
# does this system provide the log and exp functions?
include(CheckSymbolExists)
-set(CMAKE_REQUIRED_LIBRARIES "m")
check_symbol_exists(log "math.h" HAVE_LOG)
check_symbol_exists(exp "math.h" HAVE_EXP)
+if(NOT (HAVE_LOG AND HAVE_EXP))
+ unset(HAVE_LOG CACHE)
+ unset(HAVE_EXP CACHE)
+ set(CMAKE_REQUIRED_LIBRARIES "m")
+ check_symbol_exists(log "math.h" HAVE_LOG)
+ check_symbol_exists(exp "math.h" HAVE_EXP)
+ if(HAVE_LOG AND HAVE_EXP)
+ target_link_libraries(MathFunctions PRIVATE m)
+ endif()
+endif()
+# add compile definitions
if(HAVE_LOG AND HAVE_EXP)
target_compile_definitions(MathFunctions
PRIVATE "HAVE_LOG" "HAVE_EXP")
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index a844cbf..4fbcd4c 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -386,7 +386,7 @@ these functions using the :module:`CheckSymbolExists` module in the top-level
.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
:language: cmake
:start-after: # does this system provide the log and exp functions?
- :end-before: if(HAVE_LOG AND HAVE_EXP)
+ :end-before: # add compile definitions
Now let's add these defines to ``TutorialConfig.h.in`` so that we can use them
from ``mysqrt.cxx``:
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 80fae78..72de4ac 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/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 1023a66..a639b5d 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -372,11 +372,14 @@ Variables that Control the Build
/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY
/variable/CMAKE_COMPILE_PDB_OUTPUT_DIRECTORY_CONFIG
/variable/CMAKE_CONFIG_POSTFIX
+ /variable/CMAKE_CROSS_CONFIGS
/variable/CMAKE_CTEST_ARGUMENTS
/variable/CMAKE_CUDA_SEPARABLE_COMPILATION
/variable/CMAKE_CUDA_RESOLVE_DEVICE_SYMBOLS
/variable/CMAKE_CUDA_RUNTIME_LIBRARY
/variable/CMAKE_DEBUG_POSTFIX
+ /variable/CMAKE_DEFAULT_BUILD_TYPE
+ /variable/CMAKE_DEFAULT_CONFIGS
/variable/CMAKE_DISABLE_PRECOMPILE_HEADERS
/variable/CMAKE_ENABLE_EXPORTS
/variable/CMAKE_EXE_LINKER_FLAGS
@@ -428,9 +431,6 @@ Variables that Control the Build
/variable/CMAKE_MODULE_LINKER_FLAGS_INIT
/variable/CMAKE_MSVCIDE_RUN_PATH
/variable/CMAKE_MSVC_RUNTIME_LIBRARY
- /variable/CMAKE_NMC_CROSS_CONFIGS
- /variable/CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG
- /variable/CMAKE_NMC_DEFAULT_CONFIGS
/variable/CMAKE_NINJA_OUTPUT_PATH_PREFIX
/variable/CMAKE_NO_BUILTIN_CHRPATH
/variable/CMAKE_NO_SYSTEM_FROM_IMPORTED
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/Help/variable/CMAKE_NMC_CROSS_CONFIGS.rst b/Help/variable/CMAKE_CROSS_CONFIGS.rst
index 6eb6494..c850af2 100644
--- a/Help/variable/CMAKE_NMC_CROSS_CONFIGS.rst
+++ b/Help/variable/CMAKE_CROSS_CONFIGS.rst
@@ -1,5 +1,5 @@
-CMAKE_NMC_CROSS_CONFIGS
--------------------------------
+CMAKE_CROSS_CONFIGS
+-------------------
Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of
configurations available from all ``build-<Config>.ninja`` files in the
diff --git a/Help/variable/CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG.rst b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
index c0eab56..62ee0d2 100644
--- a/Help/variable/CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG.rst
+++ b/Help/variable/CMAKE_DEFAULT_BUILD_TYPE.rst
@@ -1,5 +1,5 @@
-CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG
--------------------------------------------
+CMAKE_DEFAULT_BUILD_TYPE
+------------------------
Specifies the configuration to use by default in a ``build.ninja`` file in the
:generator:`Ninja Multi-Config` generator. See the generator's documentation
diff --git a/Help/variable/CMAKE_NMC_DEFAULT_CONFIGS.rst b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
index e2bb017..86d8a5a 100644
--- a/Help/variable/CMAKE_NMC_DEFAULT_CONFIGS.rst
+++ b/Help/variable/CMAKE_DEFAULT_CONFIGS.rst
@@ -1,5 +1,5 @@
-CMAKE_NMC_DEFAULT_CONFIGS
----------------------------------
+CMAKE_DEFAULT_CONFIGS
+---------------------
Specifies a :ref:`semicolon-separated list <CMake Language Lists>` of configurations
to build for a target in ``build.ninja`` if no ``:<Config>`` suffix is specified in
diff --git a/Modules/CMakeGenericSystem.cmake b/Modules/CMakeGenericSystem.cmake
index 7efe5c4..f539b46 100644
--- a/Modules/CMakeGenericSystem.cmake
+++ b/Modules/CMakeGenericSystem.cmake
@@ -27,7 +27,7 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a")
set(CMAKE_AUTOGEN_ORIGIN_DEPENDS ON)
set(CMAKE_AUTOMOC_COMPILER_PREDEFINES ON)
set(CMAKE_AUTOMOC_PATH_PREFIX ON)
-set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE")
+set(CMAKE_AUTOMOC_MACRO_NAMES "Q_OBJECT" "Q_GADGET" "Q_NAMESPACE" "Q_NAMESPACE_EXPORT")
# basically all general purpose OSs support shared libs
set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE)
diff --git a/Modules/CheckFortranSourceCompiles.cmake b/Modules/CheckFortranSourceCompiles.cmake
index f0fde8d..3354bfb 100644
--- a/Modules/CheckFortranSourceCompiles.cmake
+++ b/Modules/CheckFortranSourceCompiles.cmake
@@ -103,8 +103,6 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
if(NOT _SRC_EXT)
set(_SRC_EXT F)
endif()
- set(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
@@ -132,10 +130,10 @@ macro(CHECK_Fortran_SOURCE_COMPILES SOURCE VAR)
try_compile(${VAR}
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
"${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
OUTPUT_VARIABLE OUTPUT)
diff --git a/Modules/CheckFortranSourceRuns.cmake b/Modules/CheckFortranSourceRuns.cmake
index a3e5d5d..f858b84 100644
--- a/Modules/CheckFortranSourceRuns.cmake
+++ b/Modules/CheckFortranSourceRuns.cmake
@@ -98,8 +98,6 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
if(NOT _SRC_EXT)
set(_SRC_EXT F90)
endif()
- set(MACRO_CHECK_FUNCTION_DEFINITIONS
- "-D${VAR} ${CMAKE_REQUIRED_FLAGS}")
if(CMAKE_REQUIRED_LINK_OPTIONS)
set(CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS
LINK_OPTIONS ${CMAKE_REQUIRED_LINK_OPTIONS})
@@ -127,10 +125,10 @@ macro(CHECK_Fortran_SOURCE_RUNS SOURCE VAR)
try_run(${VAR}_EXITCODE ${VAR}_COMPILED
${CMAKE_BINARY_DIR}
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/src.${_SRC_EXT}
- COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS}
+ COMPILE_DEFINITIONS -D${VAR} ${CMAKE_REQUIRED_DEFINITIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LINK_OPTIONS}
${CHECK_Fortran_SOURCE_COMPILES_ADD_LIBRARIES}
- CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${MACRO_CHECK_FUNCTION_DEFINITIONS}
+ CMAKE_FLAGS -DCOMPILE_DEFINITIONS:STRING=${CMAKE_REQUIRED_FLAGS}
-DCMAKE_SKIP_RPATH:BOOL=${CMAKE_SKIP_RPATH}
"${CHECK_Fortran_SOURCE_COMPILES_ADD_INCLUDES}"
COMPILE_OUTPUT_VARIABLE OUTPUT
diff --git a/Modules/CheckTypeSize.c.in b/Modules/CheckTypeSize.c.in
index 82035a3..fb93073 100644
--- a/Modules/CheckTypeSize.c.in
+++ b/Modules/CheckTypeSize.c.in
@@ -5,10 +5,14 @@
# define KEY '_','_','i','3','8','6'
#elif defined(__x86_64)
# define KEY '_','_','x','8','6','_','6','4'
-#elif defined(__ppc__)
-# define KEY '_','_','p','p','c','_','_'
+#elif defined(__PPC64__)
+# define KEY '_','_','P','P','C','6','4','_','_'
#elif defined(__ppc64__)
# define KEY '_','_','p','p','c','6','4','_','_'
+#elif defined(__PPC__)
+# define KEY '_','_','P','P','C','_','_'
+#elif defined(__ppc__)
+# define KEY '_','_','p','p','c','_','_'
#elif defined(__aarch64__)
# define KEY '_','_','a','a','r','c','h','6','4','_','_'
#elif defined(__ARM_ARCH_7A__)
diff --git a/Modules/Compiler/XL-Fortran.cmake b/Modules/Compiler/XL-Fortran.cmake
index 1683dff..e01ec8e 100644
--- a/Modules/Compiler/XL-Fortran.cmake
+++ b/Modules/Compiler/XL-Fortran.cmake
@@ -8,6 +8,7 @@ set(CMAKE_Fortran_FORMAT_FIXED_FLAG "-qfixed") # [=<right_margin>]
set(CMAKE_Fortran_FORMAT_FREE_FLAG "-qfree") # [=f90|ibm]
set(CMAKE_Fortran_MODDIR_FLAG "-qmoddir=")
+set(CMAKE_Fortran_MODDIR_INCLUDE_FLAG "-I") # -qmoddir= does not affect search path
set(CMAKE_Fortran_DEFINE_FLAG "-WF,-D")
diff --git a/Modules/FortranCInterface/CMakeLists.txt b/Modules/FortranCInterface/CMakeLists.txt
index 381080b..13e4498 100644
--- a/Modules/FortranCInterface/CMakeLists.txt
+++ b/Modules/FortranCInterface/CMakeLists.txt
@@ -101,3 +101,7 @@ set_property(TARGET symbols PROPERTY POSITION_INDEPENDENT_CODE 1)
# Require symbols through Fortran.
add_executable(FortranCInterface main.F call_sub.f ${call_mod})
target_link_libraries(FortranCInterface PUBLIC symbols)
+
+file(GENERATE OUTPUT exe-$<CONFIG>.cmake CONTENT [[
+set(FortranCInterface_EXE "$<TARGET_FILE:FortranCInterface>")
+]])
diff --git a/Modules/FortranCInterface/Detect.cmake b/Modules/FortranCInterface/Detect.cmake
index 33de6c6..c75067b 100644
--- a/Modules/FortranCInterface/Detect.cmake
+++ b/Modules/FortranCInterface/Detect.cmake
@@ -43,17 +43,11 @@ set(FortranCInterface_COMPILED ${FortranCInterface_COMPILED})
unset(FortranCInterface_COMPILED CACHE)
# Locate the sample project executable.
+set(FortranCInterface_EXE)
if(FortranCInterface_COMPILED)
- find_program(FortranCInterface_EXE
- NAMES FortranCInterface${CMAKE_EXECUTABLE_SUFFIX}
- PATHS ${FortranCInterface_BINARY_DIR} ${FortranCInterface_BINARY_DIR}/Release
- NO_DEFAULT_PATH
- )
- set(FortranCInterface_EXE ${FortranCInterface_EXE})
- unset(FortranCInterface_EXE CACHE)
+ include(${FortranCInterface_BINARY_DIR}/exe-Release.cmake OPTIONAL)
else()
set(_result "Failed to compile")
- set(FortranCInterface_EXE)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Fortran/C interface test project failed with the following output:\n"
"${FortranCInterface_OUTPUT}\n")
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 31fb0bf..d4561d5 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,7 +1,7 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 17)
-set(CMake_VERSION_PATCH 20200227)
+set(CMake_VERSION_PATCH 20200303)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/cmCPluginAPI.cxx b/Source/cmCPluginAPI.cxx
index b5c7e96..f6c1e47 100644
--- a/Source/cmCPluginAPI.cxx
+++ b/Source/cmCPluginAPI.cxx
@@ -488,24 +488,8 @@ struct cmCPluginAPISourceFile
// Keep a map from real cmSourceFile instances stored in a makefile to
// the CPluginAPI proxy source file.
-class cmCPluginAPISourceFileMap
- : public std::map<cmSourceFile*, cmCPluginAPISourceFile*>
-{
-public:
- using derived = std::map<cmSourceFile*, cmCPluginAPISourceFile*>;
- using iterator = derived::iterator;
- using value_type = derived::value_type;
- cmCPluginAPISourceFileMap() = default;
- ~cmCPluginAPISourceFileMap()
- {
- for (auto const& i : *this) {
- delete i.second;
- }
- }
- cmCPluginAPISourceFileMap(const cmCPluginAPISourceFileMap&) = delete;
- cmCPluginAPISourceFileMap& operator=(const cmCPluginAPISourceFileMap&) =
- delete;
-};
+using cmCPluginAPISourceFileMap =
+ std::map<cmSourceFile*, std::unique_ptr<cmCPluginAPISourceFile>>;
cmCPluginAPISourceFileMap cmCPluginAPISourceFiles;
void* CCONV cmCreateSourceFile(void)
@@ -536,7 +520,7 @@ void CCONV* cmGetSource(void* arg, const char* name)
auto i = cmCPluginAPISourceFiles.find(rsf);
if (i == cmCPluginAPISourceFiles.end()) {
// Create a proxy source file object for this source.
- cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+ auto sf = cm::make_unique<cmCPluginAPISourceFile>();
sf->RealSourceFile = rsf;
sf->FullPath = rsf->ResolveFullPath();
sf->SourceName =
@@ -545,10 +529,9 @@ void CCONV* cmGetSource(void* arg, const char* name)
cmSystemTools::GetFilenameLastExtension(sf->FullPath);
// Store the proxy in the map so it can be re-used and deleted later.
- cmCPluginAPISourceFileMap::value_type entry(rsf, sf);
- i = cmCPluginAPISourceFiles.insert(entry).first;
+ i = cmCPluginAPISourceFiles.emplace(rsf, std::move(sf)).first;
}
- return i->second;
+ return i->second.get();
}
return nullptr;
}
@@ -569,15 +552,16 @@ void* CCONV cmAddSource(void* arg, void* arg2)
}
// Create the proxy for the real source file.
- cmCPluginAPISourceFile* sf = new cmCPluginAPISourceFile;
+ auto sf = cm::make_unique<cmCPluginAPISourceFile>();
sf->RealSourceFile = rsf;
sf->FullPath = osf->FullPath;
sf->SourceName = osf->SourceName;
sf->SourceExtension = osf->SourceExtension;
// Store the proxy in the map so it can be re-used and deleted later.
- cmCPluginAPISourceFiles[rsf] = sf;
- return sf;
+ auto value = sf.get();
+ cmCPluginAPISourceFiles[rsf] = std::move(sf);
+ return value;
}
const char* CCONV cmSourceFileGetSourceName(void* arg)
diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx
index 04f75bd..fb100b1 100644
--- a/Source/cmCTest.cxx
+++ b/Source/cmCTest.cxx
@@ -16,6 +16,9 @@
#include <utility>
#include <vector>
+#include <cm/memory>
+#include <cmext/algorithm>
+
#include "cmsys/Base64.h"
#include "cmsys/Directory.hxx"
#include "cmsys/FStream.hxx"
@@ -32,9 +35,6 @@
# include <unistd.h> // IWYU pragma: keep
#endif
-#include <cm/memory>
-#include <cmext/algorithm>
-
#include "cmCTestBuildAndTestHandler.h"
#include "cmCTestBuildHandler.h"
#include "cmCTestConfigureHandler.h"
@@ -201,7 +201,7 @@ struct cmCTest::Private
int SubmitIndex = 0;
- cmGeneratedFileStream* OutputLogFile = nullptr;
+ std::unique_ptr<cmGeneratedFileStream> OutputLogFile;
int OutputLogFileLastTag = -1;
bool OutputTestOutputOnTestFailure = false;
@@ -362,10 +362,7 @@ cmCTest::cmCTest()
cmSystemTools::EnableVSConsoleOutput();
}
-cmCTest::~cmCTest()
-{
- delete this->Impl->OutputLogFile;
-}
+cmCTest::~cmCTest() = default;
int cmCTest::GetParallelLevel() const
{
@@ -3086,12 +3083,10 @@ bool cmCTest::RunCommand(std::vector<std::string> const& args,
void cmCTest::SetOutputLogFileName(const char* name)
{
- if (this->Impl->OutputLogFile) {
- delete this->Impl->OutputLogFile;
- this->Impl->OutputLogFile = nullptr;
- }
if (name) {
- this->Impl->OutputLogFile = new cmGeneratedFileStream(name);
+ this->Impl->OutputLogFile = cm::make_unique<cmGeneratedFileStream>(name);
+ } else {
+ this->Impl->OutputLogFile.reset();
}
}
diff --git a/Source/cmCommandArgumentParserHelper.cxx b/Source/cmCommandArgumentParserHelper.cxx
index 613ae06..379836a 100644
--- a/Source/cmCommandArgumentParserHelper.cxx
+++ b/Source/cmCommandArgumentParserHelper.cxx
@@ -5,6 +5,9 @@
#include <cstring>
#include <iostream>
#include <sstream>
+#include <utility>
+
+#include <cm/memory>
#include "cmCommandArgumentLexer.h"
#include "cmMakefile.h"
@@ -40,10 +43,10 @@ const char* cmCommandArgumentParserHelper::AddString(const std::string& str)
if (str.empty()) {
return "";
}
- char* stVal = new char[str.size() + 1];
- strcpy(stVal, str.c_str());
- this->Variables.push_back(stVal);
- return stVal;
+ auto stVal = cm::make_unique<char[]>(str.size() + 1);
+ strcpy(stVal.get(), str.c_str());
+ this->Variables.push_back(std::move(stVal));
+ return this->Variables.back().get();
}
const char* cmCommandArgumentParserHelper::ExpandSpecialVariable(
@@ -136,11 +139,11 @@ const char* cmCommandArgumentParserHelper::CombineUnions(const char* in1,
return in1;
}
size_t len = strlen(in1) + strlen(in2) + 1;
- char* out = new char[len];
- strcpy(out, in1);
- strcat(out, in2);
- this->Variables.push_back(out);
- return out;
+ auto out = cm::make_unique<char[]>(len);
+ strcpy(out.get(), in1);
+ strcat(out.get(), in2);
+ this->Variables.push_back(std::move(out));
+ return this->Variables.back().get();
}
void cmCommandArgumentParserHelper::AllocateParserType(
@@ -153,11 +156,11 @@ void cmCommandArgumentParserHelper::AllocateParserType(
if (len == 0) {
return;
}
- char* out = new char[len + 1];
- memcpy(out, str, len);
- out[len] = 0;
- pt->str = out;
- this->Variables.push_back(out);
+ auto out = cm::make_unique<char[]>(len + 1);
+ memcpy(out.get(), str, len);
+ out.get()[len] = 0;
+ pt->str = out.get();
+ this->Variables.push_back(std::move(out));
}
bool cmCommandArgumentParserHelper::HandleEscapeSymbol(
@@ -235,10 +238,7 @@ int cmCommandArgumentParserHelper::ParseString(const char* str, int verb)
void cmCommandArgumentParserHelper::CleanupParser()
{
- for (char* var : this->Variables) {
- delete[] var;
- }
- this->Variables.erase(this->Variables.begin(), this->Variables.end());
+ this->Variables.clear();
}
int cmCommandArgumentParserHelper::LexInput(char* buf, int maxlen)
diff --git a/Source/cmCommandArgumentParserHelper.h b/Source/cmCommandArgumentParserHelper.h
index 25e6892..b46edcb 100644
--- a/Source/cmCommandArgumentParserHelper.h
+++ b/Source/cmCommandArgumentParserHelper.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -69,7 +70,7 @@ private:
void CleanupParser();
void SetError(std::string const& msg);
- std::vector<char*> Variables;
+ std::vector<std::unique_ptr<char[]>> Variables;
const cmMakefile* Makefile;
std::string Result;
std::string ErrorString;
diff --git a/Source/cmDependsJavaParserHelper.cxx b/Source/cmDependsJavaParserHelper.cxx
index 516bbbf..fc1bbdd 100644
--- a/Source/cmDependsJavaParserHelper.cxx
+++ b/Source/cmDependsJavaParserHelper.cxx
@@ -8,6 +8,7 @@
#include <iostream>
#include <utility>
+#include <cm/memory>
#include <cm/string_view>
#include "cmsys/FStream.hxx"
@@ -169,10 +170,11 @@ void cmDependsJavaParserHelper::AllocateParserType(
return;
}
this->UnionsAvailable++;
- pt->str = new char[len + 1];
+ auto up = cm::make_unique<char[]>(len + 1);
+ pt->str = up.get();
strncpy(pt->str, str, len);
pt->str[len] = 0;
- this->Allocates.push_back(pt->str);
+ this->Allocates.push_back(std::move(up));
}
void cmDependsJavaParserHelper::StartClass(const char* cls)
@@ -275,10 +277,7 @@ int cmDependsJavaParserHelper::ParseString(const char* str, int verb)
void cmDependsJavaParserHelper::CleanupParser()
{
- for (char* allocate : this->Allocates) {
- delete[] allocate;
- }
- this->Allocates.erase(this->Allocates.begin(), this->Allocates.end());
+ this->Allocates.clear();
}
int cmDependsJavaParserHelper::LexInput(char* buf, int maxlen)
diff --git a/Source/cmDependsJavaParserHelper.h b/Source/cmDependsJavaParserHelper.h
index a673b5b..c545ee2 100644
--- a/Source/cmDependsJavaParserHelper.h
+++ b/Source/cmDependsJavaParserHelper.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <string>
#include <vector>
@@ -81,7 +82,7 @@ private:
int CurrentDepth;
int Verbose;
- std::vector<char*> Allocates;
+ std::vector<std::unique_ptr<char[]>> Allocates;
void PrintClasses();
diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx
index 0b72a94..a3731c1 100644
--- a/Source/cmDynamicLoader.cxx
+++ b/Source/cmDynamicLoader.cxx
@@ -6,6 +6,7 @@
#include <string>
#include <utility>
+namespace {
class cmDynamicLoaderCache
{
public:
@@ -15,14 +16,15 @@ public:
cmsys::DynamicLoader::LibraryHandle& /*p*/);
bool FlushCache(const char* path);
void FlushCache();
- static cmDynamicLoaderCache* GetInstance();
+ static cmDynamicLoaderCache& GetInstance();
private:
std::map<std::string, cmsys::DynamicLoader::LibraryHandle> CacheMap;
- static cmDynamicLoaderCache* Instance;
+ static cmDynamicLoaderCache Instance;
};
-cmDynamicLoaderCache* cmDynamicLoaderCache::Instance = nullptr;
+cmDynamicLoaderCache cmDynamicLoaderCache::Instance;
+}
cmDynamicLoaderCache::~cmDynamicLoaderCache() = default;
@@ -64,15 +66,11 @@ void cmDynamicLoaderCache::FlushCache()
for (auto const& it : this->CacheMap) {
cmsys::DynamicLoader::CloseLibrary(it.second);
}
- delete cmDynamicLoaderCache::Instance;
- cmDynamicLoaderCache::Instance = nullptr;
+ this->CacheMap.clear();
}
-cmDynamicLoaderCache* cmDynamicLoaderCache::GetInstance()
+cmDynamicLoaderCache& cmDynamicLoaderCache::GetInstance()
{
- if (!cmDynamicLoaderCache::Instance) {
- cmDynamicLoaderCache::Instance = new cmDynamicLoaderCache;
- }
return cmDynamicLoaderCache::Instance;
}
@@ -80,15 +78,15 @@ cmsys::DynamicLoader::LibraryHandle cmDynamicLoader::OpenLibrary(
const char* libname)
{
cmsys::DynamicLoader::LibraryHandle lh;
- if (cmDynamicLoaderCache::GetInstance()->GetCacheFile(libname, lh)) {
+ if (cmDynamicLoaderCache::GetInstance().GetCacheFile(libname, lh)) {
return lh;
}
lh = cmsys::DynamicLoader::OpenLibrary(libname);
- cmDynamicLoaderCache::GetInstance()->CacheFile(libname, lh);
+ cmDynamicLoaderCache::GetInstance().CacheFile(libname, lh);
return lh;
}
void cmDynamicLoader::FlushCache()
{
- cmDynamicLoaderCache::GetInstance()->FlushCache();
+ cmDynamicLoaderCache::GetInstance().FlushCache();
}
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index ac48287..0546186 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -12,6 +12,8 @@
#include <cstdlib>
#include <iterator>
#include <map>
+#include <sstream>
+#include <stdexcept>
#include <utility>
#include <cm/memory>
@@ -354,6 +356,21 @@ bool HandleInMode(std::vector<std::string> const& args,
return true;
}
+bool TryParseInteger(cmExecutionStatus& status, const std::string& str, int& i)
+{
+ try {
+ i = std::stoi(str);
+ } catch (std::invalid_argument&) {
+ std::ostringstream e;
+ e << "Invalid integer: '" << str << "'";
+ status.SetError(e.str());
+ cmSystemTools::SetFatalErrorOccured();
+ return false;
+ }
+
+ return true;
+}
+
} // anonymous namespace
bool cmForEachCommand(std::vector<std::string> const& args,
@@ -376,16 +393,28 @@ bool cmForEachCommand(std::vector<std::string> const& args,
int stop = 0;
int step = 0;
if (args.size() == 3) {
- stop = std::stoi(args[2]);
+ if (!TryParseInteger(status, args[2], stop)) {
+ return false;
+ }
}
if (args.size() == 4) {
- start = std::stoi(args[2]);
- stop = std::stoi(args[3]);
+ if (!TryParseInteger(status, args[2], start)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[3], stop)) {
+ return false;
+ }
}
if (args.size() == 5) {
- start = std::stoi(args[2]);
- stop = std::stoi(args[3]);
- step = std::stoi(args[4]);
+ if (!TryParseInteger(status, args[2], start)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[3], stop)) {
+ return false;
+ }
+ if (!TryParseInteger(status, args[4], step)) {
+ return false;
+ }
}
if (step == 0) {
if (start > stop) {
@@ -399,6 +428,7 @@ bool cmForEachCommand(std::vector<std::string> const& args,
status.SetError(
cmStrCat("called with incorrect range specification: start ", start,
", stop ", stop, ", step ", step));
+ cmSystemTools::SetFatalErrorOccured();
return false;
}
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index 2af04b6..f76e205 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -180,6 +180,7 @@ int cmGeneratedFileStreamBase::CompressFile(std::string const& oldname,
}
FILE* ifs = cmsys::SystemTools::Fopen(oldname, "r");
if (!ifs) {
+ gzclose(gf);
return 0;
}
size_t res;
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 ba2e314..0509960 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"
@@ -308,6 +309,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;
@@ -2223,11 +2231,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);
}
@@ -2269,11 +2278,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);
@@ -2284,12 +2296,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(
@@ -2320,7 +2339,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) {
@@ -2353,40 +2372,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.
@@ -2394,12 +2409,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(
@@ -5492,7 +5545,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;
@@ -5504,19 +5558,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
@@ -5529,6 +5592,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) {
@@ -5543,7 +5610,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);
}
}
@@ -5554,6 +5621,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 ||
@@ -5565,7 +5639,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) {
@@ -5595,7 +5670,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;
}
}
@@ -5991,7 +6066,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
@@ -6011,9 +6087,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, ";");
@@ -6050,7 +6128,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) {
@@ -6063,6 +6141,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) {
@@ -6076,7 +6158,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);
}
@@ -6281,6 +6364,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;
@@ -6288,6 +6377,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);
@@ -6585,11 +6677,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/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index ff6ad9d..0404715 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1361,8 +1361,43 @@ void cmGlobalGenerator::ComputeBuildFileGenerators()
}
}
+bool cmGlobalGenerator::UnsupportedVariableIsDefined(const std::string& name,
+ bool supported) const
+{
+ if (!supported && this->Makefiles.front()->GetDefinition(name)) {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "does not support variable\n"
+ " " << name << "\n"
+ "but it has been specified."
+ ;
+ /* clang-format on */
+ this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return true;
+ }
+
+ return false;
+}
+
bool cmGlobalGenerator::Compute()
{
+ // Make sure unsupported variables are not used.
+ if (this->UnsupportedVariableIsDefined("CMAKE_DEFAULT_BUILD_TYPE",
+ this->SupportsDefaultBuildType())) {
+ return false;
+ }
+ if (this->UnsupportedVariableIsDefined("CMAKE_CROSS_CONFIGS",
+ this->SupportsCrossConfigs())) {
+ return false;
+ }
+ if (this->UnsupportedVariableIsDefined("CMAKE_DEFAULT_CONFIGS",
+ this->SupportsDefaultConfigs())) {
+ return false;
+ }
+
// Some generators track files replaced during the Generate.
// Start with an empty vector:
this->FilesReplacedDuringGenerate.clear();
diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h
index 0e7e03d..ba997b2 100644
--- a/Source/cmGlobalGenerator.h
+++ b/Source/cmGlobalGenerator.h
@@ -455,6 +455,10 @@ public:
/** Generate an <output>.rule file path for a given command output. */
virtual std::string GenerateRuleFile(std::string const& output) const;
+ virtual bool SupportsDefaultBuildType() const { return false; }
+ virtual bool SupportsCrossConfigs() const { return false; }
+ virtual bool SupportsDefaultConfigs() const { return false; }
+
static std::string EscapeJSON(const std::string& s);
void ProcessEvaluationFiles();
@@ -674,6 +678,9 @@ private:
virtual const char* GetBuildIgnoreErrorsFlag() const { return nullptr; }
+ bool UnsupportedVariableIsDefined(const std::string& name,
+ bool supported) const;
+
// Cache directory content and target files to be built.
struct DirectoryContent
{
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 12a5167..86b1e0b 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -2490,8 +2490,7 @@ bool cmGlobalNinjaMultiGenerator::OpenBuildFileStreams()
return false;
}
*this->DefaultFileStream
- << "# This file is a convenience file generated by\n"
- << "# CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG.\n\n"
+ << "# Build using rules for '" << this->DefaultFileConfig << "'.\n\n"
<< "include " << GetNinjaImplFilename(this->DefaultFileConfig) << "\n\n";
}
@@ -2608,9 +2607,6 @@ bool cmGlobalNinjaMultiGenerator::InspectConfigTypeVariables()
std::string cmGlobalNinjaMultiGenerator::GetDefaultBuildConfig() const
{
- if (this->DefaultFileConfig.empty()) {
- return "Debug";
- }
return "";
}
@@ -2626,12 +2622,14 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
std::set<std::string> configs(configsVec.cbegin(), configsVec.cend());
this->DefaultFileConfig =
- state.GetSafeCacheEntryValue("CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG");
- if (!this->DefaultFileConfig.empty() &&
- !configs.count(this->DefaultFileConfig)) {
+ state.GetSafeCacheEntryValue("CMAKE_DEFAULT_BUILD_TYPE");
+ if (this->DefaultFileConfig.empty()) {
+ this->DefaultFileConfig = configsVec.front();
+ }
+ if (!configs.count(this->DefaultFileConfig)) {
std::ostringstream msg;
msg << "The configuration specified by "
- << "CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG (" << this->DefaultFileConfig
+ << "CMAKE_DEFAULT_BUILD_TYPE (" << this->DefaultFileConfig
<< ") is not present in CMAKE_CONFIGURATION_TYPES";
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
msg.str());
@@ -2639,12 +2637,12 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
}
std::vector<std::string> crossConfigsVec;
- cmExpandList(state.GetSafeCacheEntryValue("CMAKE_NMC_CROSS_CONFIGS"),
+ cmExpandList(state.GetSafeCacheEntryValue("CMAKE_CROSS_CONFIGS"),
crossConfigsVec);
auto crossConfigs = ListSubsetWithAll(configs, configs, crossConfigsVec);
if (!crossConfigs) {
std::ostringstream msg;
- msg << "CMAKE_NMC_CROSS_CONFIGS is not a subset of "
+ msg << "CMAKE_CROSS_CONFIGS is not a subset of "
<< "CMAKE_CONFIGURATION_TYPES";
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
msg.str());
@@ -2653,7 +2651,7 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
this->CrossConfigs = *crossConfigs;
auto defaultConfigsString =
- state.GetSafeCacheEntryValue("CMAKE_NMC_DEFAULT_CONFIGS");
+ state.GetSafeCacheEntryValue("CMAKE_DEFAULT_CONFIGS");
if (defaultConfigsString.empty()) {
defaultConfigsString = this->DefaultFileConfig;
}
@@ -2661,9 +2659,8 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
defaultConfigsString != this->DefaultFileConfig &&
(this->DefaultFileConfig.empty() || this->CrossConfigs.empty())) {
std::ostringstream msg;
- msg << "CMAKE_NMC_DEFAULT_CONFIGS cannot be used without "
- << "CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or "
- << "CMAKE_NMC_CROSS_CONFIGS";
+ msg << "CMAKE_DEFAULT_CONFIGS cannot be used without "
+ << "CMAKE_DEFAULT_BUILD_TYPE or CMAKE_CROSS_CONFIGS";
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
msg.str());
return false;
@@ -2677,8 +2674,7 @@ bool cmGlobalNinjaMultiGenerator::ReadCacheEntriesForBuild(
this->CrossConfigs, defaultConfigsVec);
if (!defaultConfigs) {
std::ostringstream msg;
- msg << "CMAKE_NMC_DEFAULT_CONFIGS is not a subset of "
- << "CMAKE_NMC_CROSS_CONFIGS";
+ msg << "CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS";
this->GetCMakeInstance()->IssueMessage(MessageType::FATAL_ERROR,
msg.str());
return false;
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index 3db8356..5668dd1 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -640,6 +640,10 @@ public:
bool ReadCacheEntriesForBuild(const cmState& state) override;
+ bool SupportsDefaultBuildType() const override { return true; }
+ bool SupportsCrossConfigs() const override { return true; }
+ bool SupportsDefaultConfigs() const override { return true; }
+
protected:
bool OpenBuildFileStreams() override;
void CloseBuildFileStreams() override;
diff --git a/Source/cmGlobalUnixMakefileGenerator3.cxx b/Source/cmGlobalUnixMakefileGenerator3.cxx
index d123830..7daca74 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.cxx
+++ b/Source/cmGlobalUnixMakefileGenerator3.cxx
@@ -41,7 +41,6 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
#else
this->UseLinkScript = true;
#endif
- this->CommandDatabase = nullptr;
this->IncludeDirective = "include";
this->DefineWindowsNULL = false;
@@ -49,6 +48,8 @@ cmGlobalUnixMakefileGenerator3::cmGlobalUnixMakefileGenerator3(cmake* cm)
this->UnixCD = true;
}
+cmGlobalUnixMakefileGenerator3::~cmGlobalUnixMakefileGenerator3() = default;
+
void cmGlobalUnixMakefileGenerator3::EnableLanguage(
std::vector<std::string> const& languages, cmMakefile* mf, bool optional)
{
@@ -157,10 +158,9 @@ void cmGlobalUnixMakefileGenerator3::Generate()
this->WriteMainMakefile2();
this->WriteMainCMakefile();
- if (this->CommandDatabase != nullptr) {
+ if (this->CommandDatabase) {
*this->CommandDatabase << std::endl << "]";
- delete this->CommandDatabase;
- this->CommandDatabase = nullptr;
+ this->CommandDatabase.reset();
}
}
@@ -168,11 +168,12 @@ void cmGlobalUnixMakefileGenerator3::AddCXXCompileCommand(
const std::string& sourceFile, const std::string& workingDirectory,
const std::string& compileCommand)
{
- if (this->CommandDatabase == nullptr) {
+ if (!this->CommandDatabase) {
std::string commandDatabaseName =
this->GetCMakeInstance()->GetHomeOutputDirectory() +
"/compile_commands.json";
- this->CommandDatabase = new cmGeneratedFileStream(commandDatabaseName);
+ this->CommandDatabase =
+ cm::make_unique<cmGeneratedFileStream>(commandDatabaseName);
*this->CommandDatabase << "[" << std::endl;
} else {
*this->CommandDatabase << "," << std::endl;
diff --git a/Source/cmGlobalUnixMakefileGenerator3.h b/Source/cmGlobalUnixMakefileGenerator3.h
index 340a7ef..19b2b85 100644
--- a/Source/cmGlobalUnixMakefileGenerator3.h
+++ b/Source/cmGlobalUnixMakefileGenerator3.h
@@ -68,6 +68,13 @@ public:
new cmGlobalGeneratorSimpleFactory<cmGlobalUnixMakefileGenerator3>());
}
+ ~cmGlobalUnixMakefileGenerator3() override;
+
+ cmGlobalUnixMakefileGenerator3(const cmGlobalUnixMakefileGenerator3&) =
+ delete;
+ cmGlobalUnixMakefileGenerator3& operator=(
+ const cmGlobalUnixMakefileGenerator3&) = delete;
+
//! Get the name for the generator.
std::string GetName() const override
{
@@ -232,7 +239,7 @@ protected:
std::set<cmGeneratorTarget const*>& emitted);
size_t CountProgressMarksInAll(const cmLocalGenerator& lg);
- cmGeneratedFileStream* CommandDatabase;
+ std::unique_ptr<cmGeneratedFileStream> CommandDatabase;
private:
const char* GetBuildIgnoreErrorsFlag() const override { return "-i"; }
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index 2c53a28..6e3508c 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -7,6 +7,8 @@
#include <sstream>
#include <utility>
+#include <cm/memory>
+
#ifndef CMAKE_BOOTSTRAP
# include "cmExportInstallAndroidMKGenerator.h"
#endif
@@ -33,18 +35,15 @@ cmInstallExportGenerator::cmInstallExportGenerator(
{
if (android) {
#ifndef CMAKE_BOOTSTRAP
- this->EFGen = new cmExportInstallAndroidMKGenerator(this);
+ this->EFGen = cm::make_unique<cmExportInstallAndroidMKGenerator>(this);
#endif
} else {
- this->EFGen = new cmExportInstallFileGenerator(this);
+ this->EFGen = cm::make_unique<cmExportInstallFileGenerator>(this);
}
exportSet->AddInstallation(this);
}
-cmInstallExportGenerator::~cmInstallExportGenerator()
-{
- delete this->EFGen;
-}
+cmInstallExportGenerator::~cmInstallExportGenerator() = default;
bool cmInstallExportGenerator::Compute(cmLocalGenerator* lg)
{
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index cf28b35..43dd00d 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -7,6 +7,7 @@
#include <cstddef>
#include <iosfwd>
+#include <memory>
#include <string>
#include <vector>
@@ -30,8 +31,12 @@ public:
bool exclude_from_all, std::string filename,
std::string name_space, bool exportOld,
bool android);
+ cmInstallExportGenerator(const cmInstallExportGenerator&) = delete;
~cmInstallExportGenerator() override;
+ cmInstallExportGenerator& operator=(const cmInstallExportGenerator&) =
+ delete;
+
cmExportSet* GetExportSet() { return this->ExportSet; }
bool Compute(cmLocalGenerator* lg) override;
@@ -61,7 +66,7 @@ protected:
std::string TempDir;
std::string MainImportFile;
- cmExportInstallFileGenerator* EFGen;
+ std::unique_ptr<cmExportInstallFileGenerator> EFGen;
};
#endif
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/Source/cmLocalCommonGenerator.cxx b/Source/cmLocalCommonGenerator.cxx
index 025ef7e..278ec8b 100644
--- a/Source/cmLocalCommonGenerator.cxx
+++ b/Source/cmLocalCommonGenerator.cxx
@@ -50,6 +50,15 @@ std::string cmLocalCommonGenerator::GetTargetFortranFlags(
this->Makefile->GetRequiredDefinition("CMAKE_Fortran_MODDIR_FLAG"),
mod_dir);
this->AppendFlags(flags, modflag);
+ // Some compilers do not search their own module output directory
+ // for using other modules. Add an include directory explicitly
+ // for consistency with compilers that do search it.
+ std::string incflag =
+ this->Makefile->GetSafeDefinition("CMAKE_Fortran_MODDIR_INCLUDE_FLAG");
+ if (!incflag.empty()) {
+ incflag = cmStrCat(incflag, mod_dir);
+ this->AppendFlags(flags, incflag);
+ }
}
// If there is a separate module path flag then duplicate the
diff --git a/Source/cmMachO.cxx b/Source/cmMachO.cxx
index 6cbed36..53112e0 100644
--- a/Source/cmMachO.cxx
+++ b/Source/cmMachO.cxx
@@ -79,14 +79,14 @@ public:
// A load_command and its associated data
struct RawLoadCommand
{
- uint32_t type(const cmMachOHeaderAndLoadCommands* m) const
+ uint32_t type(const cmMachOHeaderAndLoadCommands& m) const
{
if (this->LoadCommand.size() < sizeof(load_command)) {
return 0;
}
const load_command* cmd =
reinterpret_cast<const load_command*>(&this->LoadCommand[0]);
- return m->swap(cmd->cmd);
+ return m.swap(cmd->cmd);
}
std::vector<char> LoadCommand;
};
@@ -186,8 +186,11 @@ class cmMachOInternal
{
public:
cmMachOInternal(const char* fname);
+ cmMachOInternal(const cmMachOInternal&) = delete;
~cmMachOInternal();
+ cmMachOInternal& operator=(const cmMachOInternal&) = delete;
+
// read a Mach-O file
bool read_mach_o(uint32_t file_offset);
@@ -202,7 +205,7 @@ public:
std::string ErrorMessage;
// the list of Mach-O's
- std::vector<cmMachOHeaderAndLoadCommands*> MachOList;
+ std::vector<std::unique_ptr<cmMachOHeaderAndLoadCommands>> MachOList;
};
cmMachOInternal::cmMachOInternal(const char* fname)
@@ -260,12 +263,7 @@ cmMachOInternal::cmMachOInternal(const char* fname)
}
}
-cmMachOInternal::~cmMachOInternal()
-{
- for (auto& i : this->MachOList) {
- delete i;
- }
-}
+cmMachOInternal::~cmMachOInternal() = default;
bool cmMachOInternal::read_mach_o(uint32_t file_offset)
{
@@ -280,25 +278,25 @@ bool cmMachOInternal::read_mach_o(uint32_t file_offset)
return false;
}
- cmMachOHeaderAndLoadCommands* f = nullptr;
+ std::unique_ptr<cmMachOHeaderAndLoadCommands> f;
if (magic == MH_CIGAM || magic == MH_MAGIC) {
bool swap = false;
if (magic == MH_CIGAM) {
swap = true;
}
- f = new cmMachOHeaderAndLoadCommandsImpl<mach_header>(swap);
+ f = cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header>>(swap);
} else if (magic == MH_CIGAM_64 || magic == MH_MAGIC_64) {
bool swap = false;
if (magic == MH_CIGAM_64) {
swap = true;
}
- f = new cmMachOHeaderAndLoadCommandsImpl<mach_header_64>(swap);
+ f =
+ cm::make_unique<cmMachOHeaderAndLoadCommandsImpl<mach_header_64>>(swap);
}
if (f && f->read_mach_o(this->Fin)) {
- this->MachOList.push_back(f);
+ this->MachOList.push_back(std::move(f));
} else {
- delete f;
this->ErrorMessage = "Failed to read Mach-O header.";
return false;
}
@@ -333,11 +331,12 @@ bool cmMachO::GetInstallName(std::string& install_name)
}
// grab the first Mach-O and get the install name from that one
- cmMachOHeaderAndLoadCommands* macho = this->Internal->MachOList[0];
+ std::unique_ptr<cmMachOHeaderAndLoadCommands>& macho =
+ this->Internal->MachOList[0];
for (size_t i = 0; i < macho->load_commands().size(); i++) {
const cmMachOHeaderAndLoadCommands::RawLoadCommand& cmd =
macho->load_commands()[i];
- uint32_t lc_cmd = cmd.type(macho);
+ uint32_t lc_cmd = cmd.type(*macho);
if (lc_cmd == LC_ID_DYLIB || lc_cmd == LC_LOAD_WEAK_DYLIB ||
lc_cmd == LC_LOAD_DYLIB) {
if (sizeof(dylib_command) < cmd.LoadCommand.size()) {
diff --git a/Source/cmServer.cxx b/Source/cmServer.cxx
index 3b2e5f3..434fb68 100644
--- a/Source/cmServer.cxx
+++ b/Source/cmServer.cxx
@@ -59,16 +59,12 @@ cmServer::cmServer(cmConnection* conn, bool supportExperimental)
, SupportExperimental(supportExperimental)
{
// Register supported protocols:
- this->RegisterProtocol(new cmServerProtocol1);
+ this->RegisterProtocol(cm::make_unique<cmServerProtocol1>());
}
cmServer::~cmServer()
{
Close();
-
- for (cmServerProtocol* p : this->SupportedProtocols) {
- delete p;
- }
}
void cmServer::ProcessRequest(cmConnection* connection,
@@ -117,22 +113,22 @@ void cmServer::ProcessRequest(cmConnection* connection,
}
}
-void cmServer::RegisterProtocol(cmServerProtocol* protocol)
+void cmServer::RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol)
{
if (protocol->IsExperimental() && !this->SupportExperimental) {
- delete protocol;
+ protocol.reset();
return;
}
auto version = protocol->ProtocolVersion();
assert(version.first >= 0);
assert(version.second >= 0);
- auto it = std::find_if(this->SupportedProtocols.begin(),
- this->SupportedProtocols.end(),
- [version](cmServerProtocol* p) {
- return p->ProtocolVersion() == version;
- });
+ auto it = std::find_if(
+ this->SupportedProtocols.begin(), this->SupportedProtocols.end(),
+ [version](const std::unique_ptr<cmServerProtocol>& p) {
+ return p->ProtocolVersion() == version;
+ });
if (it == this->SupportedProtocols.end()) {
- this->SupportedProtocols.push_back(protocol);
+ this->SupportedProtocols.push_back(std::move(protocol));
}
}
@@ -297,19 +293,20 @@ void cmServer::WriteJsonObject(cmConnection* connection,
}
cmServerProtocol* cmServer::FindMatchingProtocol(
- const std::vector<cmServerProtocol*>& protocols, int major, int minor)
+ const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
+ int minor)
{
cmServerProtocol* bestMatch = nullptr;
- for (auto protocol : protocols) {
+ for (const auto& protocol : protocols) {
auto version = protocol->ProtocolVersion();
if (major != version.first) {
continue;
}
if (minor == version.second) {
- return protocol;
+ return protocol.get();
}
if (!bestMatch || bestMatch->ProtocolVersion().second < version.second) {
- bestMatch = protocol;
+ bestMatch = protocol.get();
}
}
return minor < 0 ? bestMatch : nullptr;
diff --git a/Source/cmServer.h b/Source/cmServer.h
index 3d7027b..ec40738 100644
--- a/Source/cmServer.h
+++ b/Source/cmServer.h
@@ -103,7 +103,7 @@ public:
cmFileMonitor* FileMonitor() const;
private:
- void RegisterProtocol(cmServerProtocol* protocol);
+ void RegisterProtocol(std::unique_ptr<cmServerProtocol> protocol);
// Callbacks from cmServerConnection:
@@ -149,12 +149,13 @@ private:
const DebugInfo* debug) const;
static cmServerProtocol* FindMatchingProtocol(
- const std::vector<cmServerProtocol*>& protocols, int major, int minor);
+ const std::vector<std::unique_ptr<cmServerProtocol>>& protocols, int major,
+ int minor);
const bool SupportExperimental;
cmServerProtocol* Protocol = nullptr;
- std::vector<cmServerProtocol*> SupportedProtocols;
+ std::vector<std::unique_ptr<cmServerProtocol>> SupportedProtocols;
friend class cmServerProtocol;
friend class cmServerRequest;
diff --git a/Source/cmSourceGroup.cxx b/Source/cmSourceGroup.cxx
index 8c3ec9f..155068cb 100644
--- a/Source/cmSourceGroup.cxx
+++ b/Source/cmSourceGroup.cxx
@@ -4,6 +4,8 @@
#include <utility>
+#include <cm/memory>
+
#include "cmStringAlgorithms.h"
class cmSourceGroupInternals
@@ -16,7 +18,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex,
const char* parentName)
: Name(std::move(name))
{
- this->Internal = new cmSourceGroupInternals;
+ this->Internal = cm::make_unique<cmSourceGroupInternals>();
this->SetGroupRegex(regex);
if (parentName) {
this->FullName = cmStrCat(parentName, '\\');
@@ -24,10 +26,7 @@ cmSourceGroup::cmSourceGroup(std::string name, const char* regex,
this->FullName += this->Name;
}
-cmSourceGroup::~cmSourceGroup()
-{
- delete this->Internal;
-}
+cmSourceGroup::~cmSourceGroup() = default;
cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
{
@@ -36,7 +35,7 @@ cmSourceGroup::cmSourceGroup(cmSourceGroup const& r)
this->GroupRegex = r.GroupRegex;
this->GroupFiles = r.GroupFiles;
this->SourceFiles = r.SourceFiles;
- this->Internal = new cmSourceGroupInternals(*r.Internal);
+ this->Internal = cm::make_unique<cmSourceGroupInternals>(*r.Internal);
}
cmSourceGroup& cmSourceGroup::operator=(cmSourceGroup const& r)
diff --git a/Source/cmSourceGroup.h b/Source/cmSourceGroup.h
index 581dc5d..623cded 100644
--- a/Source/cmSourceGroup.h
+++ b/Source/cmSourceGroup.h
@@ -5,6 +5,7 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <memory>
#include <set>
#include <string>
#include <vector>
@@ -122,7 +123,7 @@ private:
*/
std::vector<const cmSourceFile*> SourceFiles;
- cmSourceGroupInternals* Internal;
+ std::unique_ptr<cmSourceGroupInternals> Internal;
};
#endif
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index 9127c50..d8cd705 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -25,6 +25,9 @@
#endif
#if !defined(CMAKE_BOOTSTRAP)
+# if defined(_WIN32)
+# include <cm/memory>
+# endif
# include "cmCryptoHash.h"
#endif
@@ -908,7 +911,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
std::string thumbprint;
#if !defined(CMAKE_BOOTSTRAP) && defined(_WIN32)
- BYTE* certData = NULL;
CRYPT_INTEGER_BLOB cryptBlob;
HCERTSTORE certStore = NULL;
PCCERT_CONTEXT certContext = NULL;
@@ -920,12 +922,12 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
if (certFile != INVALID_HANDLE_VALUE && certFile != NULL) {
DWORD fileSize = GetFileSize(certFile, NULL);
if (fileSize != INVALID_FILE_SIZE) {
- certData = new BYTE[fileSize];
+ auto certData = cm::make_unique<BYTE[]>(fileSize);
if (certData != NULL) {
DWORD dwRead = 0;
- if (ReadFile(certFile, certData, fileSize, &dwRead, NULL)) {
+ if (ReadFile(certFile, certData.get(), fileSize, &dwRead, NULL)) {
cryptBlob.cbData = fileSize;
- cryptBlob.pbData = certData;
+ cryptBlob.pbData = certData.get();
// Verify that this is a valid cert
if (PFXIsPFXBlob(&cryptBlob)) {
@@ -961,7 +963,6 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
}
}
}
- delete[] certData;
}
}
CloseHandle(certFile);
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 8da113e..121ff6e 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -981,17 +981,11 @@ void cmVisualStudio10TargetGenerator::WriteEmbeddedResourceGroup(Elem& e0)
// If the resource was NOT added using a relative path (which should
// be the default), we have to provide a link here
if (!useRelativePath) {
- std::string link;
- if (obj.find(srcDir) == 0) {
- link = obj.substr(srcDir.length() + 1);
- } else if (obj.find(binDir) == 0) {
- link = obj.substr(binDir.length() + 1);
- } else {
+ std::string link = this->GetCSharpSourceLink(oi);
+ if (link.empty()) {
link = cmsys::SystemTools::GetFilenameName(obj);
}
- if (!link.empty()) {
- e2.Element("Link", link);
- }
+ e2.Element("Link", link);
}
// Determine if this is a generated resource from a .Designer.cs file
std::string designerResource =
@@ -1054,25 +1048,6 @@ void cmVisualStudio10TargetGenerator::WriteXamlFilesGroup(Elem& e0)
Elem e2(e1, xamlType);
this->WriteSource(e2, oi);
e2.SetHasElements();
- if (this->ProjectType == csproj && !this->InSourceBuild) {
- // add <Link> tag to written XAML source if necessary
- const std::string& srcDir =
- this->Makefile->GetCurrentSourceDirectory();
- const std::string& binDir =
- this->Makefile->GetCurrentBinaryDirectory();
- std::string link;
- if (obj.find(srcDir) == 0) {
- link = obj.substr(srcDir.length() + 1);
- } else if (obj.find(binDir) == 0) {
- link = obj.substr(binDir.length() + 1);
- } else {
- link = cmsys::SystemTools::GetFilenameName(obj);
- }
- if (!link.empty()) {
- ConvertToWindowsSlash(link);
- e2.Element("Link", link);
- }
- }
e2.Element("SubType", "Designer");
}
}
@@ -1442,13 +1417,8 @@ void cmVisualStudio10TargetGenerator::WriteCustomRule(
} else {
Elem e1(e0, "ItemGroup");
Elem e2(e1, "None");
- std::string link;
- this->GetCSharpSourceLink(source, link);
this->WriteSource(e2, source);
e2.SetHasElements();
- if (!link.empty()) {
- e2.Element("Link", link);
- }
}
for (std::string const& c : this->Configurations) {
cmCustomCommandGenerator ccg(command, c, lg);
@@ -1805,30 +1775,8 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
std::string copyToOutDir;
std::string includeInVsix;
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
- if (this->ProjectType == csproj) {
- // EVERY extra source file must have a <Link>, otherwise it might not
- // be visible in Visual Studio at all. The path relative to current
- // source- or binary-dir is used within the link, if the file is
- // in none of these paths, it is added with the plain filename without
- // any path. This means the file will show up at root-level of the csproj
- // (where CMakeLists.txt etc. are).
- if (!this->InSourceBuild) {
- toolHasSettings = true;
- std::string fullFileName = sf->GetFullPath();
- std::string srcDir = this->Makefile->GetCurrentSourceDirectory();
- std::string binDir = this->Makefile->GetCurrentBinaryDirectory();
- if (fullFileName.find(binDir) != std::string::npos) {
- sourceLink.clear();
- } else if (fullFileName.find(srcDir) != std::string::npos) {
- sourceLink = fullFileName.substr(srcDir.length() + 1);
- } else {
- // fallback: add plain filename without any path
- sourceLink = cmsys::SystemTools::GetFilenameName(fullFileName);
- }
- if (!sourceLink.empty()) {
- ConvertToWindowsSlash(sourceLink);
- }
- }
+ if (this->ProjectType == csproj && !this->InSourceBuild) {
+ toolHasSettings = true;
}
if (ext == "hlsl") {
tool = "FXCompile";
@@ -2047,9 +1995,6 @@ void cmVisualStudio10TargetGenerator::WriteExtraSource(Elem& e1,
if (!settingsLastGenOutput.empty()) {
e2.Element("LastGenOutput", settingsLastGenOutput);
}
- if (!sourceLink.empty()) {
- e2.Element("Link", sourceLink);
- }
if (!subType.empty()) {
e2.Element("SubType", subType);
}
@@ -2102,6 +2047,20 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
ConvertToWindowsSlash(sourceFile);
e2.Attribute("Include", sourceFile);
+ if (this->ProjectType == csproj && !this->InSourceBuild) {
+ // For out of source projects we have to provide a link (if not specified
+ // via property) for every source file (besides .cs files) otherwise they
+ // will not be visible in VS at all.
+ // First we check if the file is in a source group, then we check if the
+ // file path is relative to current source- or binary-dir, otherwise it is
+ // added with the plain filename without any path. This means the file will
+ // show up at root-level of the csproj (where CMakeLists.txt etc. are).
+ std::string link = this->GetCSharpSourceLink(sf);
+ if (link.empty())
+ link = cmsys::SystemTools::GetFilenameName(sf->GetFullPath());
+ e2.Element("Link", link);
+ }
+
ToolSource toolSource = { sf, forceRelative };
this->Tools[e2.Tag].push_back(toolSource);
}
@@ -2461,12 +2420,6 @@ void cmVisualStudio10TargetGenerator::OutputSourceSpecificFlags(
std::string f = source->GetFullPath();
using CsPropMap = std::map<std::string, std::string>;
CsPropMap sourceFileTags;
- // set <Link> tag if necessary
- std::string link;
- this->GetCSharpSourceLink(source, link);
- if (!link.empty()) {
- sourceFileTags["Link"] = link;
- }
this->GetCSharpSourceProperties(&sf, sourceFileTags);
// write source file specific tags
if (!sourceFileTags.empty()) {
@@ -4869,24 +4822,34 @@ void cmVisualStudio10TargetGenerator::WriteCSharpSourceProperties(
}
}
-void cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
- cmSourceFile const* sf, std::string& link)
+std::string cmVisualStudio10TargetGenerator::GetCSharpSourceLink(
+ cmSourceFile const* source)
{
- std::string const& sourceFilePath = sf->GetFullPath();
- std::string const& binaryDir = LocalGenerator->GetCurrentBinaryDirectory();
-
- if (!cmSystemTools::IsSubDirectory(sourceFilePath, binaryDir)) {
- const std::string& stripFromPath =
- this->Makefile->GetCurrentSourceDirectory();
- if (sourceFilePath.find(stripFromPath) == 0) {
- if (const char* l = sf->GetProperty("VS_CSHARP_Link")) {
- link = l;
- } else {
- link = sourceFilePath.substr(stripFromPath.length() + 1);
- }
- ConvertToWindowsSlash(link);
- }
- }
+ // For out of source files, we first check if a matching source group
+ // for this file exists, otherwise we check if the path relative to current
+ // source- or binary-dir is used within the link and return that
+ std::string link;
+ std::string const& fullFileName = source->GetFullPath();
+ std::string const& srcDir = this->Makefile->GetCurrentSourceDirectory();
+ std::string const& binDir = this->Makefile->GetCurrentBinaryDirectory();
+ // unfortunately we have to copy the source groups, because
+ // FindSourceGroup uses a regex which is modifying the group
+ std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
+ cmSourceGroup* sourceGroup =
+ this->Makefile->FindSourceGroup(fullFileName, sourceGroups);
+ if (sourceGroup && !sourceGroup->GetFullName().empty()) {
+ link = sourceGroup->GetFullName() + "/" +
+ cmsys::SystemTools::GetFilenameName(fullFileName);
+ } else if (fullFileName.find(srcDir) == 0) {
+ link = fullFileName.substr(srcDir.length() + 1);
+ } else if (fullFileName.find(binDir) == 0) {
+ link = fullFileName.substr(binDir.length() + 1);
+ } else if (const char* l = source->GetProperty("VS_CSHARP_Link")) {
+ link = l;
+ }
+
+ ConvertToWindowsSlash(link);
+ return link;
}
std::string cmVisualStudio10TargetGenerator::GetCMakeFilePath(
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 30027c9..4977c1a 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -183,7 +183,7 @@ private:
std::map<std::string, std::string>& tags);
void WriteCSharpSourceProperties(
Elem& e2, const std::map<std::string, std::string>& tags);
- void GetCSharpSourceLink(cmSourceFile const* sf, std::string& link);
+ std::string GetCSharpSourceLink(cmSourceFile const* source);
private:
friend class cmVS10GeneratorOptions;
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/CMakeLists.txt b/Tests/CMakeLists.txt
index 33c7514..6f86a5f 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1605,7 +1605,7 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
DEPENDS ExternalProjectUpdateSetup )
# do each of the tutorial steps
- function(add_tutorial_test step_name use_mymath)
+ function(add_tutorial_test step_name use_mymath tutorial_arg pass_regex)
set(tutorial_test_name Tutorial${step_name})
set(tutorial_build_dir "${CMake_BINARY_DIR}/Tests/Tutorial/${step_name}")
if (use_mymath)
@@ -1623,19 +1623,28 @@ ${CMake_SOURCE_DIR}/Utilities/Release/push.bash --dir dev -- '${CMake_BUILD_NIGH
${build_generator_args}
--build-project Tutorial
--build-options ${tutorial_build_options}
- --test-command Tutorial 25.0)
+ --test-command Tutorial ${tutorial_arg})
+ set_tests_properties(${tutorial_test_name} PROPERTIES
+ PASS_REGULAR_EXPRESSION ${pass_regex})
+
list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/${tutorial_build_dir}_Build")
endfunction()
if(NOT CMake_TEST_EXTERNAL_CMAKE)
foreach(STP RANGE 2 12)
- add_tutorial_test(Step${STP} TRUE)
+ if (STP EQUAL 6)
+ set(pass_regex ".*using log and exp")
+ else()
+ set(pass_regex "The square root of 25 is 5")
+ endif()
+ add_tutorial_test(Step${STP} TRUE 25 ${pass_regex})
endforeach()
- add_tutorial_test(Complete TRUE)
+ set(pass_regex "The square root of 25 is 5")
+ add_tutorial_test(Complete TRUE 25 ${pass_regex})
foreach(STP RANGE 3 12)
- add_tutorial_test(Step${STP} FALSE)
+ add_tutorial_test(Step${STP} FALSE 25 ${pass_regex})
endforeach()
- add_tutorial_test(Complete FALSE)
+ add_tutorial_test(Complete FALSE 25 ${pass_regex})
endif()
add_test(testing ${CMAKE_CTEST_COMMAND} -C \${CTEST_CONFIGURATION_TYPE}
diff --git a/Tests/CSharpOnly/CMakeLists.txt b/Tests/CSharpOnly/CMakeLists.txt
index 82049c7..42cbe2e 100644
--- a/Tests/CSharpOnly/CMakeLists.txt
+++ b/Tests/CSharpOnly/CMakeLists.txt
@@ -2,7 +2,9 @@
project (CSharpOnly CSharp)
# C# does not make any difference between STATIC and SHARED libs
-add_library(lib1 STATIC lib1.cs)
+add_library(lib1 STATIC lib1.cs nested/lib1.cs)
+#without the source group this test will fail to compile
+source_group(nested FILES nested/lib1.cs)
add_library(lib2 SHARED lib2.cs)
add_executable(CSharpOnly csharponly.cs)
diff --git a/Tests/CSharpOnly/csharponly.cs b/Tests/CSharpOnly/csharponly.cs
index ad4641a..3890c82 100644
--- a/Tests/CSharpOnly/csharponly.cs
+++ b/Tests/CSharpOnly/csharponly.cs
@@ -5,10 +5,8 @@ namespace CSharpOnly
public static void Main(string[] args)
{
int val = Lib1.getResult();
-
Lib2 l = new Lib2();
- val = l.myVal;
-
+ val = val + l.myVal + nested.Lib1.getResult();
return;
}
}
diff --git a/Tests/CSharpOnly/nested/lib1.cs b/Tests/CSharpOnly/nested/lib1.cs
new file mode 100644
index 0000000..c2fde4b
--- /dev/null
+++ b/Tests/CSharpOnly/nested/lib1.cs
@@ -0,0 +1,13 @@
+namespace CSharpOnly
+{
+ namespace nested
+ {
+ public class Lib1
+ {
+ public static int getResult()
+ {
+ return 23;
+ }
+ }
+ }
+}
diff --git a/Tests/FortranModules/CMakeLists.txt b/Tests/FortranModules/CMakeLists.txt
index d056b43..b7a6f68 100644
--- a/Tests/FortranModules/CMakeLists.txt
+++ b/Tests/FortranModules/CMakeLists.txt
@@ -21,7 +21,7 @@ end module parent
submodule ( parent ) child
contains
module procedure id
- f = x
+ id = x
end procedure id
end submodule child
program main
diff --git a/Tests/FortranOnly/CMakeLists.txt b/Tests/FortranOnly/CMakeLists.txt
index d945375..4327c2f 100644
--- a/Tests/FortranOnly/CMakeLists.txt
+++ b/Tests/FortranOnly/CMakeLists.txt
@@ -51,40 +51,36 @@ add_custom_target(checksayhello ALL
)
add_dependencies(checksayhello sayhello)
-# Exclude this test on IBM XL for now because the check strangely
-# fails with 'ld: 0706-029 Use a number with the -H flag'.
-if(NOT CMAKE_Fortran_COMPILER_ID STREQUAL XL)
- set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log)
- file(REMOVE "${err_log}")
- include(CheckFortranSourceCompiles)
- unset(HAVE_PRINT CACHE)
- CHECK_Fortran_SOURCE_COMPILES([[
+set(err_log ${CMAKE_BINARY_DIR}/CMakeFiles/CMakeError.log)
+file(REMOVE "${err_log}")
+include(CheckFortranSourceCompiles)
+unset(HAVE_PRINT CACHE)
+CHECK_Fortran_SOURCE_COMPILES([[
PROGRAM TEST_HAVE_PRINT
PRINT *, 'Hello'
END
]] HAVE_PRINT)
- if(NOT HAVE_PRINT)
- if(EXISTS "${err_log}")
- file(READ "${err_log}" err)
- endif()
- string(REPLACE "\n" "\n " err " ${err}")
- message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n"
- "${err}")
+if(NOT HAVE_PRINT)
+ if(EXISTS "${err_log}")
+ file(READ "${err_log}" err)
endif()
+ string(REPLACE "\n" "\n " err " ${err}")
+ message(SEND_ERROR "CHECK_Fortran_SOURCE_COMPILES for HAVE_PRINT failed:\n"
+ "${err}")
+endif()
- unset(Fortran_BOGUS_FLAG CACHE)
- include(CheckFortranCompilerFlag)
- CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG)
- if (Fortran_BOGUS_FLAG)
- message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed")
- endif()
+unset(Fortran_BOGUS_FLAG CACHE)
+include(CheckFortranCompilerFlag)
+CHECK_Fortran_COMPILER_FLAG(-_this_is_not_a_flag_ Fortran_BOGUS_FLAG)
+if (Fortran_BOGUS_FLAG)
+ message(SEND_ERROR "CHECK_Fortran_COMPILER_FLAG() succeeded, but should have failed")
+endif()
- unset(Fortran_RUN_FLAG CACHE)
- include(CheckFortranSourceRuns)
- check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90)
- if(NOT Fortran_RUN_FLAG)
- message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed")
- endif()
+unset(Fortran_RUN_FLAG CACHE)
+include(CheckFortranSourceRuns)
+check_fortran_source_runs("program a; end program" Fortran_RUN_FLAG SRC_EXT F90)
+if(NOT Fortran_RUN_FLAG)
+ message(SEND_ERROR "CHECK_Fortran_SOURCE_RUNS() failed")
endif()
# Test generation of preprocessed sources.
diff --git a/Tests/Preprocess/preprocess.c b/Tests/Preprocess/preprocess.c
index 958c77e..b3117da 100644
--- a/Tests/Preprocess/preprocess.c
+++ b/Tests/Preprocess/preprocess.c
@@ -15,21 +15,21 @@ int check_defines_C(void)
result = 0;
}
if (strcmp(TARGET_STRING, STRING_VALUE) != 0) {
- fprintf(stderr, "TARGET_STRING has wrong value in C [%s]\n",
- TARGET_STRING);
+ fprintf(stderr, "TARGET_STRING has wrong value in C [%s] vs [%s]\n",
+ TARGET_STRING, STRING_VALUE);
result = 0;
}
{
int x = 2;
int y = 3;
if ((FILE_EXPR) != (EXPR)) {
- fprintf(stderr, "FILE_EXPR did not work in C [%s]\n",
- TO_STRING(FILE_EXPR));
+ fprintf(stderr, "FILE_EXPR did not work in C [%s] vs [%s]\n",
+ TO_STRING(FILE_EXPR), TO_STRING(EXPR));
result = 0;
}
if ((TARGET_EXPR) != (EXPR)) {
- fprintf(stderr, "TARGET_EXPR did not work in C [%s]\n",
- TO_STRING(FILE_EXPR));
+ fprintf(stderr, "TARGET_EXPR did not work in C [%s] vs [%s]\n",
+ TO_STRING(TARGET_EXPR), TO_STRING(EXPR));
result = 0;
}
}
diff --git a/Tests/Preprocess/preprocess.cxx b/Tests/Preprocess/preprocess.cxx
index 34a69c6..f2fffef 100644
--- a/Tests/Preprocess/preprocess.cxx
+++ b/Tests/Preprocess/preprocess.cxx
@@ -12,25 +12,26 @@ int check_defines_CXX()
{
int result = 1;
if (strcmp(FILE_STRING, STRING_VALUE) != 0) {
- fprintf(stderr, "FILE_STRING has wrong value in CXX [%s]\n", FILE_STRING);
+ fprintf(stderr, "FILE_STRING has wrong value in CXX [%s] vs [%s]\n",
+ FILE_STRING, STRING_VALUE);
result = 0;
}
if (strcmp(TARGET_STRING, STRING_VALUE) != 0) {
- fprintf(stderr, "TARGET_STRING has wrong value in CXX [%s]\n",
- TARGET_STRING);
+ fprintf(stderr, "TARGET_STRING has wrong value in CXX [%s] vs [%s]\n",
+ TARGET_STRING, STRING_VALUE);
result = 0;
}
{
int x = 2;
int y = 3;
if ((FILE_EXPR) != (EXPR)) {
- fprintf(stderr, "FILE_EXPR did not work in CXX [%s]\n",
- TO_STRING(FILE_EXPR));
+ fprintf(stderr, "FILE_EXPR did not work in CXX [%s] vs [%s]\n",
+ TO_STRING(FILE_EXPR), TO_STRING(EXPR));
result = 0;
}
if ((TARGET_EXPR) != (EXPR)) {
- fprintf(stderr, "TARGET_EXPR did not work in CXX [%s]\n",
- TO_STRING(FILE_EXPR));
+ fprintf(stderr, "TARGET_EXPR did not work in CXX [%s] vs [%s]\n",
+ TO_STRING(TARGET_EXPR), TO_STRING(EXPR));
result = 0;
}
}
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-result.txt b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-result.txt
+++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-result.txt
diff --git a/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt
new file mode 100644
index 0000000..a5d149d
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error:
+ Generator
+
+ [^
+]*
+
+ does not support variable
+
+ CMAKE_CROSS_CONFIGS
+
+ but it has been specified.
diff --git a/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake
new file mode 100644
index 0000000..75d0c47
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_CROSS_CONFIGS.cmake
@@ -0,0 +1 @@
+set(CMAKE_CROSS_CONFIGS "")
diff --git a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/Languages/LINK_LANGUAGE-genex-result.txt
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-result.txt
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt
new file mode 100644
index 0000000..8aa3ed3
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error:
+ Generator
+
+ [^
+]*
+
+ does not support variable
+
+ CMAKE_DEFAULT_BUILD_TYPE
+
+ but it has been specified.
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake
new file mode 100644
index 0000000..64c7feb
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_BUILD_TYPE.cmake
@@ -0,0 +1 @@
+set(CMAKE_DEFAULT_BUILD_TYPE "")
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt
new file mode 100644
index 0000000..040bf4d
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error:
+ Generator
+
+ [^
+]*
+
+ does not support variable
+
+ CMAKE_DEFAULT_CONFIGS
+
+ but it has been specified.
diff --git a/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake
new file mode 100644
index 0000000..5b65172
--- /dev/null
+++ b/Tests/RunCMake/Configure/NoCMAKE_DEFAULT_CONFIGS.cmake
@@ -0,0 +1 @@
+set(CMAKE_DEFAULT_CONFIGS "")
diff --git a/Tests/RunCMake/Configure/RunCMakeTest.cmake b/Tests/RunCMake/Configure/RunCMakeTest.cmake
index 76d843c..9fd4499 100644
--- a/Tests/RunCMake/Configure/RunCMakeTest.cmake
+++ b/Tests/RunCMake/Configure/RunCMakeTest.cmake
@@ -50,3 +50,9 @@ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
run_cmake(RemoveCache)
file(REMOVE "${RunCMake_TEST_BINARY_DIR}/CMakeCache.txt")
run_cmake(RemoveCache)
+
+if(NOT RunCMake_GENERATOR MATCHES "^Ninja Multi-Config$")
+ run_cmake(NoCMAKE_CROSS_CONFIGS)
+ run_cmake(NoCMAKE_DEFAULT_BUILD_TYPE)
+ run_cmake(NoCMAKE_DEFAULT_CONFIGS)
+endif()
diff --git a/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/GeneratorExpression/LINK_LANGUAGE-add_custom_command-result.txt
@@ -0,0 +1 @@
+1
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/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt
index 6e165e8..76c5ecf 100644
--- a/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidCrossConfigs-stderr.txt
@@ -1,5 +1,5 @@
^CMake Error:
- CMAKE_NMC_CROSS_CONFIGS is not a subset of CMAKE_CONFIGURATION_TYPES
+ CMAKE_CROSS_CONFIGS is not a subset of CMAKE_CONFIGURATION_TYPES
CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt
index 114a8a3..5aa9038 100644
--- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultBuildFileConfig-stderr.txt
@@ -1,6 +1,6 @@
^CMake Error:
- The configuration specified by CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG
- \(RelWithDebInfo\) is not present in CMAKE_CONFIGURATION_TYPES
+ The configuration specified by CMAKE_DEFAULT_BUILD_TYPE \(RelWithDebInfo\) is
+ not present in CMAKE_CONFIGURATION_TYPES
CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt
index 8d52189..6c2df86 100644
--- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsCross-stderr.txt
@@ -1,5 +1,5 @@
^CMake Error:
- CMAKE_NMC_DEFAULT_CONFIGS is not a subset of CMAKE_NMC_CROSS_CONFIGS
+ CMAKE_DEFAULT_CONFIGS is not a subset of CMAKE_CROSS_CONFIGS
CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt
index f9cb56d..5d090a0 100644
--- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt
+++ b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoCross-stderr.txt
@@ -1,6 +1,6 @@
^CMake Error:
- CMAKE_NMC_DEFAULT_CONFIGS cannot be used without
- CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or CMAKE_NMC_CROSS_CONFIGS
+ CMAKE_DEFAULT_CONFIGS cannot be used without CMAKE_DEFAULT_BUILD_TYPE or
+ CMAKE_CROSS_CONFIGS
CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-stderr.txt b/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-stderr.txt
deleted file mode 100644
index f9cb56d..0000000
--- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile-stderr.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-^CMake Error:
- CMAKE_NMC_DEFAULT_CONFIGS cannot be used without
- CMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG or CMAKE_NMC_CROSS_CONFIGS
-
-
-CMake Generate step failed\. Build files cannot be regenerated correctly\.$
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index a608e9e..b07b4f7 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -81,7 +81,9 @@ endfunction()
set(RunCMake_TEST_NO_CLEAN 1)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Simple-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=RelWithDebInfo;-DCMAKE_NMC_CROSS_CONFIGS=all")
+# IMPORTANT: Setting RelWithDebInfo as the first item in CMAKE_CONFIGURATION_TYPES
+# generates a build.ninja file with that configuration
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=RelWithDebInfo\\;Debug\\;Release\\;MinSizeRel;-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(Simple)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -113,7 +115,7 @@ run_ninja(Simple default-build-file-clean-minsizerel build.ninja clean:MinSizeRe
run_ninja(Simple default-build-file-all build.ninja all)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAlias-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all;-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=all;-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(SimpleDefaultBuildAlias)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -122,7 +124,7 @@ run_ninja(SimpleDefaultBuildAlias all build.ninja all)
run_ninja(SimpleDefaultBuildAlias clean build.ninja clean)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasList-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(SimpleDefaultBuildAliasList)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -133,7 +135,7 @@ run_ninja(SimpleDefaultBuildAliasList all-relwithdebinfo build.ninja all:RelWith
run_ninja(SimpleDefaultBuildAliasList clean-configs build.ninja clean)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleDefaultBuildAliasListCross-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=RelWithDebInfo;-DCMAKE_NMC_DEFAULT_CONFIGS=all;-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=RelWithDebInfo;-DCMAKE_DEFAULT_CONFIGS=all;-DCMAKE_CROSS_CONFIGS=Debug\\;Release")
run_cmake_configure(SimpleDefaultBuildAliasListCross)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -141,27 +143,23 @@ run_ninja(SimpleDefaultBuildAliasListCross target-configs build.ninja simpleexe)
unset(RunCMake_TEST_BINARY_DIR)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
run_cmake(InvalidCrossConfigs)
unset(RunCMake_TEST_OPTIONS)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=RelWithDebInfo")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_DEFAULT_BUILD_TYPE=RelWithDebInfo")
run_cmake(InvalidDefaultBuildFileConfig)
unset(RunCMake_TEST_OPTIONS)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=Debug\\;Release\\;RelWithDebInfo")
run_cmake(InvalidDefaultConfigsCross)
unset(RunCMake_TEST_OPTIONS)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all")
-run_cmake(InvalidDefaultConfigsNoDefaultFile)
-unset(RunCMake_TEST_OPTIONS)
-
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release;-DCMAKE_NMC_DEFAULT_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release;-DCMAKE_DEFAULT_CONFIGS=all")
run_cmake(InvalidDefaultConfigsNoCross)
unset(RunCMake_TEST_OPTIONS)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_DEFAULT_BUILD_FILE_CONFIG=Release")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_DEFAULT_BUILD_TYPE=Release")
run_cmake(DefaultBuildFileConfig)
unset(RunCMake_TEST_OPTIONS)
@@ -178,7 +176,7 @@ run_ninja(SimpleNoCross all-all build-Debug.ninja all:all)
run_cmake_build(SimpleNoCross all-clean Debug clean:all)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SimpleCrossConfigs-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=Debug\\;Release")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=Debug\\;Release")
run_cmake_configure(SimpleCrossConfigs)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
run_ninja(SimpleCrossConfigs release-in-release-graph build-Release.ninja simpleexe)
@@ -192,21 +190,21 @@ run_cmake_build(SimpleCrossConfigs all-all-in-release-graph Release all:all)
run_cmake_build(SimpleCrossConfigs all-relwithdebinfo-in-release-graph Release all:RelWithDebInfo)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Framework-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(Framework)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
run_cmake_build(Framework framework Debug all)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/FrameworkDependencyAutogen-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(FrameworkDependencyAutogen)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
run_cmake_build(FrameworkDependencyAutogen framework Release test2:Debug)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandGenerator-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(CustomCommandGenerator)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -223,7 +221,7 @@ run_ninja(CustomCommandGenerator release-in-debug-graph build-Debug.ninja genera
run_cmake_command(CustomCommandGenerator-release-in-debug-graph-generated "${TARGET_FILE_generated_Release}")
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CustomCommandsAndTargets-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(CustomCommandsAndTargets)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -243,7 +241,7 @@ unset(RunCMake_TEST_BINARY_DIR)
run_cmake(CustomCommandDepfile)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PostfixAndLocation-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(PostfixAndLocation)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -258,14 +256,14 @@ run_ninja(Clean release-notall build-Release.ninja exenotall)
run_cmake_build(Clean release-clean Release clean)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/AdditionalCleanFiles-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo;-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(AdditionalCleanFiles)
unset(RunCMake_TEST_OPTIONS)
run_cmake_build(AdditionalCleanFiles release-clean Release clean)
run_ninja(AdditionalCleanFiles all-clean build-Debug.ninja clean:all)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Install-build)
-set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_NMC_CROSS_CONFIGS=all")
+set(RunCMake_TEST_OPTIONS "-DCMAKE_INSTALL_PREFIX=${RunCMake_TEST_BINARY_DIR}/install;-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(Install)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
@@ -287,7 +285,7 @@ endif()
if(CMake_TEST_Qt5)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Qt5-build)
- set(RunCMake_TEST_OPTIONS "-DCMAKE_NMC_CROSS_CONFIGS=all")
+ set(RunCMake_TEST_OPTIONS "-DCMAKE_CROSS_CONFIGS=all")
run_cmake_configure(Qt5)
unset(RunCMake_TEST_OPTIONS)
include(${RunCMake_TEST_BINARY_DIR}/target_files.cmake)
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs
new file mode 100644
index 0000000..3695dc9
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/foo.cs
@@ -0,0 +1,3 @@
+void foo()
+{
+}
diff --git a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile.cmake b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
index e69de29..e69de29 100644
--- a/Tests/RunCMake/NinjaMultiConfig/InvalidDefaultConfigsNoDefaultFile.cmake
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/images/empty.bmp
diff --git a/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs
new file mode 100644
index 0000000..d5d334a
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/CSharpSourceGroup/nested/baz.cs
@@ -0,0 +1,3 @@
+void baz()
+{
+}
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index ff31a74..3ca7cc0 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -3,12 +3,12 @@ cmake_policy(SET CMP0057 NEW)
include(RunCMake)
cmake_policy(SET CMP0054 NEW)
+run_cmake(VsCsharpSourceGroup)
run_cmake(VsCSharpCompilerOpts)
run_cmake(ExplicitCMakeLists)
run_cmake(RuntimeLibrary)
run_cmake(SourceGroupCMakeLists)
run_cmake(SourceGroupTreeCMakeLists)
-
run_cmake(VsConfigurationType)
run_cmake(VsTargetsFileReferences)
run_cmake(VsCustomProps)
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
new file mode 100644
index 0000000..3b5c70f
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup-check.cmake
@@ -0,0 +1,22 @@
+set(csProjFile "${RunCMake_TEST_BINARY_DIR}/VsCsharpSourceGroup.csproj")
+if(NOT EXISTS "${csProjFile}")
+ set(RunCMake_TEST_FAILED "Project file ${csProjFile} does not exist.")
+ return()
+endif()
+
+file(STRINGS "${csProjFile}" lines)
+
+include(${RunCMake_TEST_SOURCE_DIR}/VsCsharpSourceGroupHelpers.cmake)
+
+set(SOURCE_GROUPS_TO_FIND
+ "CSharpSourceGroup"
+ "CSharpSourceGroup/nested"
+ "Images"
+)
+
+foreach(GROUP_NAME IN LISTS ${SOURCE_GROUPS_TO_FIND})
+ find_source_group("${lines}" ${GROUP_NAME})
+ if(NOT ${SOURCE_GROUP_FOUND})
+ return()
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake
new file mode 100644
index 0000000..024993c
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroup.cmake
@@ -0,0 +1,16 @@
+enable_language(CSharp)
+set(CMAKE_CONFIGURATION_TYPES Debug)
+
+set(SRC_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs
+ ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs
+)
+
+set(IMAGE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/Images/empty.bmp
+)
+
+add_library(VsCsharpSourceGroup SHARED ${SRC_FILES} ${IMAGE_FILES})
+source_group("CSharpSourceGroup" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/foo.cs)
+source_group("CSharpSourceGroup/nested" FILES ${CMAKE_CURRENT_SOURCE_DIR}/CSharpSourceGroup/nested/baz.cs)
+source_group("Images" FILES ${IMAGE_FILES})
diff --git a/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake
new file mode 100644
index 0000000..bfa9a67
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsCsharpSourceGroupHelpers.cmake
@@ -0,0 +1,15 @@
+function(find_source_group LINES NAME)
+ set(foundSourceGroupLink 0)
+ foreach(line IN LISTS LINES)
+ if(line MATCHES "<Link>${NAME}</Link>")
+ set(foundSourceGroupLink 1)
+ endif()
+ endforeach()
+
+ if(NOT foundSourceGroupLink)
+ set(RunCMake_TEST_FAILED "Source group link for ${NAME} not found." PARENT_SCOPE)
+ set(SOURCE_GROUP_FOUND 0 PARENT_SCOPE)
+ return()
+ endif()
+ set(SOURCE_GROUP_FOUND 1 PARENT_SCOPE)
+endfunction()
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/foreach/RunCMakeTest.cmake b/Tests/RunCMake/foreach/RunCMakeTest.cmake
index 8f50203..22a0a75 100644
--- a/Tests/RunCMake/foreach/RunCMakeTest.cmake
+++ b/Tests/RunCMake/foreach/RunCMakeTest.cmake
@@ -12,3 +12,10 @@ run_cmake(foreach-ZIP_LISTS-with-LISTS-mix-test)
run_cmake(foreach-ZIP_LISTS-multiple-iter-vars-test)
run_cmake(foreach-ZIP_LISTS-iter-vars-mismatch-test-1)
run_cmake(foreach-ZIP_LISTS-iter-vars-mismatch-test-2)
+run_cmake(foreach-RANGE-non-int-test-1)
+run_cmake(foreach-RANGE-non-int-test-2-1)
+run_cmake(foreach-RANGE-non-int-test-2-2)
+run_cmake(foreach-RANGE-non-int-test-3-1)
+run_cmake(foreach-RANGE-non-int-test-3-2)
+run_cmake(foreach-RANGE-non-int-test-3-3)
+run_cmake(foreach-RANGE-invalid-test)
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-stderr.txt
new file mode 100644
index 0000000..66efdc1
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at foreach-RANGE-invalid-test\.cmake:[0-9]+ \(foreach\):
+ foreach called with incorrect range specification: start 2, stop 1, step 1
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-invalid-test.cmake b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test.cmake
new file mode 100644
index 0000000..2f8eaba
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-invalid-test.cmake
@@ -0,0 +1,2 @@
+foreach(a RANGE 2 1 1)
+endforeach()
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-stderr.txt
new file mode 100644
index 0000000..78355dc
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at foreach-RANGE-non-int-test-1\.cmake:[0-9]+ \(foreach\):
+ foreach Invalid integer: 'b'
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1.cmake
new file mode 100644
index 0000000..452fbdf
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-1.cmake
@@ -0,0 +1,2 @@
+foreach(a RANGE b)
+endforeach()
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-stderr.txt
new file mode 100644
index 0000000..787ffc1
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at foreach-RANGE-non-int-test-2-1\.cmake:[0-9]+ \(foreach\):
+ foreach Invalid integer: 'b'
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1.cmake
new file mode 100644
index 0000000..885c805
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-1.cmake
@@ -0,0 +1,2 @@
+foreach(a RANGE b 1)
+endforeach()
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-stderr.txt
new file mode 100644
index 0000000..70cc73f
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at foreach-RANGE-non-int-test-2-2\.cmake:[0-9]+ \(foreach\):
+ foreach Invalid integer: 'b'
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2.cmake
new file mode 100644
index 0000000..d52aeb9
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-2-2.cmake
@@ -0,0 +1,2 @@
+foreach(a RANGE 1 b)
+endforeach()
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-stderr.txt
new file mode 100644
index 0000000..5803fe8
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at foreach-RANGE-non-int-test-3-1\.cmake:[0-9]+ \(foreach\):
+ foreach Invalid integer: 'b'
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1.cmake
new file mode 100644
index 0000000..33a488d
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-1.cmake
@@ -0,0 +1,2 @@
+foreach(a RANGE b 1 1)
+endforeach()
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-stderr.txt
new file mode 100644
index 0000000..189c60d
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at foreach-RANGE-non-int-test-3-2\.cmake:[0-9]+ \(foreach\):
+ foreach Invalid integer: 'b'
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2.cmake
new file mode 100644
index 0000000..ff119d3
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-2.cmake
@@ -0,0 +1,2 @@
+foreach(a RANGE 1 b 1)
+endforeach()
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-result.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-stderr.txt b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-stderr.txt
new file mode 100644
index 0000000..ee9e62c
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at foreach-RANGE-non-int-test-3-3\.cmake:[0-9]+ \(foreach\):
+ foreach Invalid integer: 'b'
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:3 \(include\)$
diff --git a/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3.cmake b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3.cmake
new file mode 100644
index 0000000..fdebdf0
--- /dev/null
+++ b/Tests/RunCMake/foreach/foreach-RANGE-non-int-test-3-3.cmake
@@ -0,0 +1,2 @@
+foreach(a RANGE 1 1 b)
+endforeach()
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}>)