summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--.gitlab-ci.yml47
-rw-r--r--.gitlab/ci/configure_debian10_aarch64_extdeps.cmake1
-rw-r--r--.gitlab/ci/configure_debian10_aarch64_ninja.cmake2
-rw-r--r--.gitlab/ci/configure_debian10_extdeps.cmake1
-rw-r--r--.gitlab/ci/configure_debian10_ninja.cmake2
-rw-r--r--.gitlab/ci/configure_extdeps_common.cmake5
-rw-r--r--.gitlab/ci/configure_fedora36_extdeps.cmake1
-rw-r--r--.gitlab/ci/configure_fedora36_makefiles.cmake2
-rw-r--r--.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake4
-rw-r--r--.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake4
-rw-r--r--.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake2
-rw-r--r--.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake1
-rw-r--r--.gitlab/ci/configure_windows_vs2022_x64_ninja_multi.cmake1
-rw-r--r--.gitlab/ci/ctest_standalone.cmake6
-rw-r--r--.gitlab/ci/cxx_modules_rules_gcc.cmake10
-rw-r--r--.gitlab/ci/cxx_modules_rules_msvc.cmake11
-rwxr-xr-x.gitlab/ci/docker/debian10-aarch64/install_deps.sh15
-rwxr-xr-x.gitlab/ci/docker/debian10/install_deps.sh15
-rw-r--r--.gitlab/ci/docker/fedora36/Dockerfile9
-rwxr-xr-x.gitlab/ci/docker/fedora36/install_clang_tidy_headers.sh18
-rwxr-xr-x.gitlab/ci/docker/fedora36/install_deps.sh15
-rw-r--r--.gitlab/ci/docker/gcc_cxx_modules/Dockerfile9
-rwxr-xr-x.gitlab/ci/docker/gcc_cxx_modules/install_deps.sh7
-rwxr-xr-x.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh26
-rw-r--r--.gitlab/ci/env_debian10_aarch64_extdeps.sh1
-rw-r--r--.gitlab/ci/env_debian10_extdeps.sh1
-rw-r--r--.gitlab/ci/env_extdeps_common.sh5
-rw-r--r--.gitlab/ci/env_fedora36_extdeps.sh1
-rwxr-xr-x.gitlab/ci/extdeps-linux.sh62
-rw-r--r--.gitlab/os-linux.yml56
-rw-r--r--Auxiliary/cmake-mode.el42
-rw-r--r--Auxiliary/vim/indent/cmake.vim4
-rw-r--r--Auxiliary/vim/syntax/cmake.vim10
-rw-r--r--CMakeLists.txt7
-rw-r--r--CTestCustom.cmake.in6
-rw-r--r--CompileFlags.cmake11
-rw-r--r--Copyright.txt1
-rw-r--r--Help/command/FIND_XXX.txt21
-rw-r--r--Help/command/block.rst75
-rw-r--r--Help/command/cmake_language.rst28
-rw-r--r--Help/command/cmake_policy.rst41
-rw-r--r--Help/command/ctest_run_script.rst6
-rw-r--r--Help/command/ctest_start.rst2
-rw-r--r--Help/command/ctest_test.rst10
-rw-r--r--Help/command/enable_language.rst9
-rw-r--r--Help/command/endblock.rst11
-rw-r--r--Help/command/export.rst16
-rw-r--r--Help/command/file.rst7
-rw-r--r--Help/command/find_package.rst3
-rw-r--r--Help/command/foreach.rst8
-rw-r--r--Help/command/function.rst6
-rw-r--r--Help/command/get_test_property.rst3
-rw-r--r--Help/command/if.rst7
-rw-r--r--Help/command/install.rst49
-rw-r--r--Help/command/message.rst7
-rw-r--r--Help/command/return.rst36
-rw-r--r--Help/command/set.rst17
-rw-r--r--Help/command/target_sources.rst77
-rw-r--r--Help/command/try_compile.rst52
-rw-r--r--Help/command/try_run.rst89
-rw-r--r--Help/command/while.rst8
-rw-r--r--Help/cpack_gen/archive.rst6
-rw-r--r--Help/cpack_gen/external.rst4
-rw-r--r--Help/cpack_gen/freebsd.rst12
-rw-r--r--Help/cpack_gen/nuget.rst8
-rw-r--r--Help/cpack_gen/rpm.rst2
-rw-r--r--Help/dev/experimental.rst26
-rw-r--r--Help/envvar/CMAKE_GENERATOR.rst6
-rw-r--r--Help/envvar/CMAKE_GENERATOR_PLATFORM.rst2
-rw-r--r--Help/envvar/CMAKE_GENERATOR_TOOLSET.rst2
-rw-r--r--Help/envvar/CTEST_PROGRESS_OUTPUT.rst4
-rw-r--r--Help/envvar/DESTDIR.rst5
-rw-r--r--Help/generator/Green Hills MULTI.rst12
-rw-r--r--Help/generator/Ninja Multi-Config.rst4
-rw-r--r--Help/generator/Visual Studio 10 2010.rst4
-rw-r--r--Help/generator/Visual Studio 11 2012.rst4
-rw-r--r--Help/generator/Visual Studio 12 2013.rst4
-rw-r--r--Help/generator/Visual Studio 14 2015.rst4
-rw-r--r--Help/generator/Visual Studio 15 2017.rst4
-rw-r--r--Help/generator/Visual Studio 16 2019.rst4
-rw-r--r--Help/generator/Visual Studio 17 2022.rst4
-rw-r--r--Help/generator/Visual Studio 9 2008.rst2
-rw-r--r--Help/generator/Xcode.rst2
-rw-r--r--Help/guide/ide-integration/index.rst17
-rw-r--r--Help/guide/tutorial/A Basic Starting Point.rst468
-rw-r--r--Help/guide/tutorial/Adding Generator Expressions.rst12
-rw-r--r--Help/guide/tutorial/Adding Support for a Testing Dashboard.rst20
-rw-r--r--Help/guide/tutorial/Adding System Introspection.rst10
-rw-r--r--Help/guide/tutorial/Adding Usage Requirements for a Library.rst146
-rw-r--r--Help/guide/tutorial/Adding a Custom Command and Generated File.rst12
-rw-r--r--Help/guide/tutorial/Adding a Library.rst464
-rw-r--r--Help/guide/tutorial/Complete/CMakeLists.txt3
-rw-r--r--Help/guide/tutorial/Complete/License.txt2
-rw-r--r--Help/guide/tutorial/Installing and Testing.rst8
-rw-r--r--Help/guide/tutorial/Packaging Debug and Release.rst6
-rw-r--r--Help/guide/tutorial/Packaging an Installer.rst10
-rw-r--r--Help/guide/tutorial/Selecting Static or Shared Libraries.rst14
-rw-r--r--Help/guide/tutorial/Step1/CMakeLists.txt16
-rw-r--r--Help/guide/tutorial/Step1/TutorialConfig.h.in2
-rw-r--r--Help/guide/tutorial/Step1/tutorial.cxx7
-rw-r--r--Help/guide/tutorial/Step10/CMakeLists.txt33
-rw-r--r--Help/guide/tutorial/Step10/License.txt2
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt67
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h15
-rw-r--r--Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx4
-rw-r--r--Help/guide/tutorial/Step10/TutorialConfig.h.in1
-rw-r--r--Help/guide/tutorial/Step10/tutorial.cxx15
-rw-r--r--Help/guide/tutorial/Step11/CMakeLists.txt6
-rw-r--r--Help/guide/tutorial/Step11/License.txt2
-rw-r--r--Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt2
-rw-r--r--Help/guide/tutorial/Step11/tutorial.cxx1
-rw-r--r--Help/guide/tutorial/Step12/CMakeLists.txt3
-rw-r--r--Help/guide/tutorial/Step12/License.txt2
-rw-r--r--Help/guide/tutorial/Step2/CMakeLists.txt23
-rw-r--r--Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt2
-rw-r--r--Help/guide/tutorial/Step2/TutorialConfig.h.in2
-rw-r--r--Help/guide/tutorial/Step2/tutorial.cxx8
-rw-r--r--Help/guide/tutorial/Step3/CMakeLists.txt4
-rw-r--r--Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt4
-rw-r--r--Help/guide/tutorial/Step5/CMakeLists.txt52
-rw-r--r--Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt4
-rw-r--r--Help/guide/tutorial/Step6/CMakeLists.txt17
-rw-r--r--Help/guide/tutorial/Step6/CTestConfig.cmake7
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt26
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/MakeTable.cxx25
-rw-r--r--Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx8
-rw-r--r--Help/guide/tutorial/Step7/CMakeLists.txt19
-rw-r--r--Help/guide/tutorial/Step7/CTestConfig.cmake7
-rw-r--r--Help/guide/tutorial/Step7/License.txt2
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt25
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/MakeTable.cxx25
-rw-r--r--Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx9
-rw-r--r--Help/guide/tutorial/Step8/CMakeLists.txt28
-rw-r--r--Help/guide/tutorial/Step8/License.txt2
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt48
-rw-r--r--Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx17
-rw-r--r--Help/guide/tutorial/Step9/CMakeLists.txt24
-rw-r--r--Help/guide/tutorial/Step9/License.txt2
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt7
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx19
-rw-r--r--Help/guide/tutorial/Step9/MathFunctions/mysqrt.h6
-rw-r--r--Help/guide/tutorial/index.rst4
-rw-r--r--Help/guide/user-interaction/index.rst107
-rw-r--r--Help/manual/OPTIONS_BUILD.txt103
-rw-r--r--Help/manual/OPTIONS_HELP.txt68
-rw-r--r--Help/manual/ccmake.1.rst4
-rw-r--r--Help/manual/cmake-commands.7.rst2
-rw-r--r--Help/manual/cmake-generator-expressions.7.rst4
-rw-r--r--Help/manual/cmake-generators.7.rst16
-rw-r--r--Help/manual/cmake-gui.1.rst16
-rw-r--r--Help/manual/cmake-modules.7.rst2
-rw-r--r--Help/manual/cmake-policies.7.rst8
-rw-r--r--Help/manual/cmake-presets.7.rst533
-rw-r--r--Help/manual/cmake-properties.7.rst18
-rw-r--r--Help/manual/cmake-toolchains.7.rst3
-rw-r--r--Help/manual/cmake-variables.7.rst10
-rw-r--r--Help/manual/cmake.1.rst367
-rw-r--r--Help/manual/cpack.1.rst52
-rw-r--r--Help/manual/ctest.1.rst451
-rw-r--r--Help/manual/presets/schema.json200
-rw-r--r--Help/module/FindOpenSP.rst1
-rw-r--r--Help/module/FindSDL_gfx.rst1
-rw-r--r--Help/policy/CMP0140.rst17
-rw-r--r--Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst5
-rw-r--r--Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst5
-rw-r--r--Help/prop_test/LABELS.rst2
-rw-r--r--Help/prop_tgt/COMPILE_WARNING_AS_ERROR.rst4
-rw-r--r--Help/prop_tgt/CUDA_STANDARD.rst6
-rw-r--r--Help/prop_tgt/CXX_MODULE_DIRS.rst17
-rw-r--r--Help/prop_tgt/CXX_MODULE_DIRS_NAME.rst17
-rw-r--r--Help/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS.rst17
-rw-r--r--Help/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS_NAME.rst19
-rw-r--r--Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SET.rst18
-rw-r--r--Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SETS.rst18
-rw-r--r--Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SET_NAME.rst19
-rw-r--r--Help/prop_tgt/CXX_MODULE_SET.rst18
-rw-r--r--Help/prop_tgt/CXX_MODULE_SETS.rst16
-rw-r--r--Help/prop_tgt/CXX_MODULE_SET_NAME.rst18
-rw-r--r--Help/prop_tgt/CXX_STANDARD.rst6
-rw-r--r--Help/prop_tgt/EXPORT_NO_SYSTEM.rst11
-rw-r--r--Help/prop_tgt/HIP_STANDARD.rst6
-rw-r--r--Help/prop_tgt/IMPORTED_NO_SYSTEM.rst12
-rw-r--r--Help/prop_tgt/INTERFACE_CXX_MODULE_HEADER_UNIT_SETS.rst16
-rw-r--r--Help/prop_tgt/INTERFACE_CXX_MODULE_SETS.rst16
-rw-r--r--Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst5
-rw-r--r--Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst4
-rw-r--r--Help/prop_tgt/OBJCXX_STANDARD.rst6
-rw-r--r--Help/prop_tgt/SYSTEM.rst16
-rw-r--r--Help/prop_tgt/XCODE_GENERATE_SCHEME.rst4
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_ENABLE_GPU_API_VALIDATION.rst14
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION.rst14
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_LAUNCH_CONFIGURATION.rst13
-rw-r--r--Help/prop_tgt/XCODE_SCHEME_LAUNCH_MODE.rst22
-rw-r--r--Help/release/dev/0-sample-topic.rst7
-rw-r--r--Help/release/dev/E-capabilities-tls.rst5
-rw-r--r--Help/release/dev/FindOpenSP-module.rst4
-rw-r--r--Help/release/dev/FindVulkan-dxc.rst5
-rw-r--r--Help/release/dev/LINUX.rst4
-rw-r--r--Help/release/dev/block-command.rst5
-rw-r--r--Help/release/dev/bsd-variables.rst9
-rw-r--r--Help/release/dev/cmake-E-env-modify.rst5
-rw-r--r--Help/release/dev/cmake-presets-package.rst5
-rw-r--r--Help/release/dev/cmake_language_GET_MESSAGE_LOG_LEVEL.rst6
-rw-r--r--Help/release/dev/compiler-launcher-genexp.rst5
-rw-r--r--Help/release/dev/cpack-archive-custom-extension.rst6
-rw-r--r--Help/release/dev/cpack-reuse-cmake-tools.rst7
-rw-r--r--Help/release/dev/cuda-device-lto.rst7
-rw-r--r--Help/release/dev/cxx_std_26.rst8
-rw-r--r--Help/release/dev/find-cuda-toolkit-nvtx3.rst8
-rw-r--r--Help/release/dev/find_item-VALIDATOR.rst6
-rw-r--r--Help/release/dev/find_package-one-more-path.rst6
-rw-r--r--Help/release/dev/finddoxygen-better-version-checking.rst11
-rw-r--r--Help/release/dev/findopenal-add-import-library.rst4
-rw-r--r--Help/release/dev/findvulkan-volk.rst5
-rw-r--r--Help/release/dev/p1689r5.rst6
-rw-r--r--Help/release/dev/return-PROPAGATE.rst5
-rw-r--r--Help/release/dev/system.rst15
-rw-r--r--Help/release/dev/try_compile-signatures.rst8
-rw-r--r--Help/release/dev/try_run_split_output.rst6
-rw-r--r--Help/release/dev/xcode-gpu-validation.rst12
-rw-r--r--Help/release/dev/xcode-launch-mode.rst12
-rw-r--r--Help/release/index.rst2
-rw-r--r--Help/variable/BSD.rst6
-rw-r--r--Help/variable/CMAKE_BINARY_DIR.rst2
-rw-r--r--Help/variable/CMAKE_CPACK_COMMAND.rst6
-rw-r--r--Help/variable/CMAKE_CTEST_COMMAND.rst6
-rw-r--r--Help/variable/CMAKE_CURRENT_BINARY_DIR.rst2
-rw-r--r--Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst2
-rw-r--r--Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst2
-rw-r--r--Help/variable/CMAKE_FIND_DEBUG_MODE.rst2
-rw-r--r--Help/variable/CMAKE_GENERATOR.rst2
-rw-r--r--Help/variable/CMAKE_GENERATOR_PLATFORM.rst2
-rw-r--r--Help/variable/CMAKE_GENERATOR_TOOLSET.rst2
-rw-r--r--Help/variable/CMAKE_INSTALL_PREFIX.rst5
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER.rst3
-rw-r--r--Help/variable/CMAKE_LANG_COMPILER_ID.rst91
-rw-r--r--Help/variable/CMAKE_MAKE_PROGRAM.rst4
-rw-r--r--Help/variable/CMAKE_MESSAGE_CONTEXT.rst2
-rw-r--r--Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst10
-rw-r--r--Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst7
-rw-r--r--Help/variable/CMAKE_SCRIPT_MODE_FILE.rst4
-rw-r--r--Help/variable/CMAKE_SOURCE_DIR.rst2
-rw-r--r--Help/variable/CMAKE_WARN_DEPRECATED.rst3
-rw-r--r--Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst4
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION.rst13
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION.rst13
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION.rst12
-rw-r--r--Help/variable/CMAKE_XCODE_SCHEME_LAUNCH_MODE.rst13
-rw-r--r--Help/variable/CPACK_CUSTOM_INSTALL_VARIABLES.rst2
-rw-r--r--Help/variable/CTEST_CONFIGURATION_TYPE.rst2
-rw-r--r--Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst2
-rw-r--r--Help/variable/DRAGONFLYBSD.rst6
-rw-r--r--Help/variable/FREEBSD.rst6
-rw-r--r--Help/variable/LINUX.rst6
-rw-r--r--Help/variable/NETBSD.rst6
-rw-r--r--Help/variable/OPENBSD.rst6
-rw-r--r--Modules/CMakeDetermineCUDACompiler.cmake5
-rw-r--r--Modules/CMakeDetermineCompileFeatures.cmake19
-rw-r--r--Modules/CMakeDetermineCompilerABI.cmake3
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake8
-rw-r--r--Modules/CMakeDetermineFortranCompiler.cmake36
-rw-r--r--Modules/CMakeFindFrameworks.cmake9
-rw-r--r--Modules/CMakeParseImplicitLinkInfo.cmake7
-rw-r--r--Modules/CMakeSwiftInformation.cmake2
-rw-r--r--Modules/CMakeTestCUDACompiler.cmake6
-rw-r--r--Modules/CPack.cmake52
-rw-r--r--Modules/CTestTargets.cmake2
-rw-r--r--Modules/CTestUseLaunchers.cmake7
-rw-r--r--Modules/CheckIPOSupported.cmake40
-rw-r--r--Modules/Compiler/Clang-CUDA.cmake4
-rw-r--r--Modules/Compiler/Clang.cmake1
-rw-r--r--Modules/Compiler/IntelLLVM-FindBinUtils.cmake45
-rw-r--r--Modules/Compiler/IntelLLVM.cmake21
-rw-r--r--Modules/Compiler/MSVC-CXX.cmake1
-rw-r--r--Modules/Compiler/NVIDIA-CUDA.cmake24
-rw-r--r--Modules/ExternalProject.cmake14
-rw-r--r--Modules/FetchContent.cmake7
-rw-r--r--Modules/FindBLAS.cmake11
-rw-r--r--Modules/FindCUDA.cmake4
-rw-r--r--Modules/FindCUDAToolkit.cmake32
-rw-r--r--Modules/FindCURL.cmake5
-rw-r--r--Modules/FindCoin3D.cmake4
-rw-r--r--Modules/FindDoxygen.cmake46
-rw-r--r--Modules/FindGLEW.cmake27
-rw-r--r--Modules/FindGTK2.cmake1
-rw-r--r--Modules/FindICU.cmake12
-rw-r--r--Modules/FindLAPACK.cmake12
-rw-r--r--Modules/FindMatlab.cmake26
-rw-r--r--Modules/FindOpenACC.cmake10
-rw-r--r--Modules/FindOpenAL.cmake26
-rw-r--r--Modules/FindOpenGL.cmake2
-rw-r--r--Modules/FindOpenMP.cmake62
-rw-r--r--Modules/FindOpenSP.cmake155
-rw-r--r--Modules/FindOpenSSL.cmake22
-rw-r--r--Modules/FindPython/Support.cmake274
-rw-r--r--Modules/FindRuby.cmake53
-rw-r--r--Modules/FindSDL_gfx.cmake86
-rw-r--r--Modules/FindSDL_image.cmake4
-rw-r--r--Modules/FindSDL_mixer.cmake4
-rw-r--r--Modules/FindSDL_net.cmake4
-rw-r--r--Modules/FindSDL_sound.cmake25
-rw-r--r--Modules/FindSDL_ttf.cmake4
-rw-r--r--Modules/FindVulkan.cmake117
-rw-r--r--Modules/Internal/CPack/CPackDeb.cmake30
-rw-r--r--Modules/Internal/CPack/CPackRPM.cmake6
-rw-r--r--Modules/Platform/AIX-GNU.cmake4
-rw-r--r--Modules/Platform/AIX-XL.cmake4
-rwxr-xr-xModules/Platform/AIX/ExportImportList46
-rw-r--r--Modules/Platform/DragonFly.cmake2
-rw-r--r--Modules/Platform/FreeBSD.cmake2
-rw-r--r--Modules/Platform/Linux-IntelLLVM.cmake26
-rw-r--r--Modules/Platform/Linux-NVHPC.cmake16
-rw-r--r--Modules/Platform/Linux.cmake1
-rw-r--r--Modules/Platform/NetBSD.cmake2
-rw-r--r--Modules/Platform/OpenBSD.cmake2
-rw-r--r--Modules/Platform/SerenityOS-Clang-ASM.cmake2
-rw-r--r--Modules/Platform/SerenityOS-Clang-C.cmake2
-rw-r--r--Modules/Platform/SerenityOS-Clang-CXX.cmake2
-rw-r--r--Modules/Platform/SerenityOS-GNU-ASM.cmake2
-rw-r--r--Modules/Platform/SerenityOS-GNU-C.cmake2
-rw-r--r--Modules/Platform/SerenityOS-GNU-CXX.cmake2
-rw-r--r--Modules/Platform/SerenityOS-GNU.cmake24
-rw-r--r--Modules/Platform/SerenityOS.cmake12
-rw-r--r--Modules/Platform/Windows-IntelLLVM.cmake51
-rw-r--r--Modules/Platform/kFreeBSD.cmake3
-rw-r--r--Source/CMakeLists.txt9
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cmCPackArchiveGenerator.cxx12
-rw-r--r--Source/CPack/cmCPackFreeBSDGenerator.cxx54
-rw-r--r--Source/CPack/cpack.cxx171
-rw-r--r--Source/CTest/cmCTestCoverageCommand.cxx12
-rw-r--r--Source/CTest/cmCTestCoverageCommand.h6
-rw-r--r--Source/CTest/cmCTestHandlerCommand.cxx20
-rw-r--r--Source/CTest/cmCTestHandlerCommand.h5
-rw-r--r--Source/CTest/cmCTestRunTest.cxx146
-rw-r--r--Source/CTest/cmCTestSubmitCommand.cxx65
-rw-r--r--Source/CTest/cmCTestSubmitCommand.h13
-rw-r--r--Source/CTest/cmCTestUploadCommand.cxx2
-rw-r--r--Source/CTest/cmCTestUploadCommand.h5
-rw-r--r--Source/CursesDialog/cmCursesLongMessageForm.cxx2
-rw-r--r--Source/CursesDialog/form/.gitattributes1
-rw-r--r--Source/CursesDialog/form/fty_int.c2
-rw-r--r--Source/CursesDialog/form/fty_num.c2
-rw-r--r--Source/LexerParser/cmFortranLexer.cxx377
-rw-r--r--Source/LexerParser/cmFortranLexer.in.l16
-rw-r--r--Source/LexerParser/cmFortranParser.cxx324
-rw-r--r--Source/LexerParser/cmFortranParser.y18
-rw-r--r--Source/QtDialog/FirstConfigure.cxx3
-rw-r--r--Source/cmArgumentParser.cxx186
-rw-r--r--Source/cmArgumentParser.h400
-rw-r--r--Source/cmArgumentParserTypes.h69
-rw-r--r--Source/cmBlockCommand.cxx197
-rw-r--r--Source/cmBlockCommand.h14
-rw-r--r--Source/cmCMakeHostSystemInformationCommand.cxx12
-rw-r--r--Source/cmCMakeLanguageCommand.cxx35
-rw-r--r--Source/cmCMakePathCommand.cxx134
-rw-r--r--Source/cmCMakePresetsGraph.cxx164
-rw-r--r--Source/cmCMakePresetsGraph.h65
-rw-r--r--Source/cmCMakePresetsGraphInternal.h4
-rw-r--r--Source/cmCMakePresetsGraphReadJSON.cxx52
-rw-r--r--Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx95
-rw-r--r--Source/cmCommands.cxx12
-rw-r--r--Source/cmCommonTargetGenerator.cxx4
-rw-r--r--Source/cmConfigure.cmake.h.in4
-rw-r--r--Source/cmCoreTryCompile.cxx695
-rw-r--r--Source/cmCoreTryCompile.h76
-rw-r--r--Source/cmCreateTestSourceList.cxx4
-rw-r--r--Source/cmCxxModuleMapper.cxx308
-rw-r--r--Source/cmCxxModuleMapper.h85
-rw-r--r--Source/cmDefinePropertyCommand.cxx5
-rw-r--r--Source/cmDocumentation.cxx42
-rw-r--r--Source/cmExecuteProcessCommand.cxx12
-rw-r--r--Source/cmExecutionStatus.h17
-rw-r--r--Source/cmExperimental.cxx63
-rw-r--r--Source/cmExperimental.h21
-rw-r--r--Source/cmExportBuildFileGenerator.cxx98
-rw-r--r--Source/cmExportBuildFileGenerator.h16
-rw-r--r--Source/cmExportCommand.cxx23
-rw-r--r--Source/cmExportFileGenerator.cxx33
-rw-r--r--Source/cmExportFileGenerator.h5
-rw-r--r--Source/cmExportInstallAndroidMKGenerator.cxx3
-rw-r--r--Source/cmExportInstallFileGenerator.cxx108
-rw-r--r--Source/cmExportInstallFileGenerator.h25
-rw-r--r--Source/cmExportTryCompileFileGenerator.h3
-rw-r--r--Source/cmFileAPICodemodel.cxx16
-rw-r--r--Source/cmFileCommand.cxx402
-rw-r--r--Source/cmFindBase.cxx62
-rw-r--r--Source/cmFindBase.h7
-rw-r--r--Source/cmFindLibraryCommand.cxx33
-rw-r--r--Source/cmFindPackageCommand.cxx1265
-rw-r--r--Source/cmFindPackageCommand.h2
-rw-r--r--Source/cmFindPathCommand.cxx6
-rw-r--r--Source/cmFindProgramCommand.cxx12
-rw-r--r--Source/cmForEachCommand.cxx2
-rw-r--r--Source/cmFunctionBlocker.cxx18
-rw-r--r--Source/cmFunctionBlocker.h2
-rw-r--r--Source/cmFunctionCommand.cxx1
-rw-r--r--Source/cmGeneratedFileStream.cxx6
-rw-r--r--Source/cmGeneratorTarget.cxx131
-rw-r--r--Source/cmGeneratorTarget.h35
-rw-r--r--Source/cmGhsMultiTargetGenerator.cxx4
-rw-r--r--Source/cmGlobalGenerator.cxx9
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx546
-rw-r--r--Source/cmGlobalNinjaGenerator.h4
-rw-r--r--Source/cmGlobalVisualStudio10Generator.cxx21
-rw-r--r--Source/cmGlobalVisualStudio10Generator.h3
-rw-r--r--Source/cmGlobalVisualStudio7Generator.cxx15
-rw-r--r--Source/cmGlobalVisualStudio7Generator.h2
-rw-r--r--Source/cmGlobalVisualStudioVersionedGenerator.cxx37
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx38
-rw-r--r--Source/cmIfCommand.cxx2
-rw-r--r--Source/cmInstallCommand.cxx157
-rw-r--r--Source/cmInstallCommandArguments.h5
-rw-r--r--Source/cmInstallCxxModuleBmiGenerator.cxx75
-rw-r--r--Source/cmInstallCxxModuleBmiGenerator.h52
-rw-r--r--Source/cmInstallExportGenerator.cxx73
-rw-r--r--Source/cmInstallExportGenerator.h8
-rw-r--r--Source/cmLinkLineDeviceComputer.cxx21
-rw-r--r--Source/cmLinkLineDeviceComputer.h1
-rw-r--r--Source/cmListFileCache.cxx11
-rw-r--r--Source/cmLocalGenerator.cxx32
-rw-r--r--Source/cmLocalGenerator.h13
-rw-r--r--Source/cmLocalUnixMakefileGenerator3.cxx37
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx3
-rw-r--r--Source/cmMacroCommand.cxx2
-rw-r--r--Source/cmMakefile.cxx99
-rw-r--r--Source/cmMakefile.h20
-rw-r--r--Source/cmMakefileExecutableTargetGenerator.cxx27
-rw-r--r--Source/cmMakefileLibraryTargetGenerator.cxx25
-rw-r--r--Source/cmMakefileTargetGenerator.cxx136
-rw-r--r--Source/cmMakefileTargetGenerator.h20
-rw-r--r--Source/cmMessageCommand.cxx65
-rw-r--r--Source/cmMessageType.h16
-rw-r--r--Source/cmNinjaNormalTargetGenerator.cxx1
-rw-r--r--Source/cmNinjaTargetGenerator.cxx327
-rw-r--r--Source/cmParseArgumentsCommand.cxx17
-rw-r--r--Source/cmPolicies.h4
-rw-r--r--Source/cmQtAutoGenInitializer.cxx3
-rw-r--r--Source/cmReturnCommand.cxx44
-rw-r--r--Source/cmScanDepFormat.cxx37
-rw-r--r--Source/cmScanDepFormat.h5
-rw-r--r--Source/cmScriptGenerator.cxx2
-rw-r--r--Source/cmSetPropertyCommand.cxx4
-rw-r--r--Source/cmStandardLevelResolver.cxx35
-rw-r--r--Source/cmStringCommand.cxx5
-rw-r--r--Source/cmSystemTools.cxx237
-rw-r--r--Source/cmSystemTools.h64
-rw-r--r--Source/cmTarget.cxx124
-rw-r--r--Source/cmTarget.h10
-rw-r--r--Source/cmTargetCompileDefinitionsCommand.cxx4
-rw-r--r--Source/cmTargetExport.h2
-rw-r--r--Source/cmTargetIncludeDirectoriesCommand.cxx3
-rw-r--r--Source/cmTargetLinkLibrariesCommand.cxx8
-rw-r--r--Source/cmTargetPrecompileHeadersCommand.cxx4
-rw-r--r--Source/cmTargetSourcesCommand.cxx47
-rw-r--r--Source/cmTryCompileCommand.cxx58
-rw-r--r--Source/cmTryCompileCommand.h30
-rw-r--r--Source/cmTryRunCommand.cxx339
-rw-r--r--Source/cmTryRunCommand.h44
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx71
-rw-r--r--Source/cmVisualStudio10TargetGenerator.h1
-rw-r--r--Source/cmVisualStudioGeneratorOptions.cxx71
-rw-r--r--Source/cmWhileCommand.cxx2
-rw-r--r--Source/cmXCodeScheme.cxx34
-rw-r--r--Source/cmake.cxx74
-rw-r--r--Source/cmake.h29
-rw-r--r--Source/cmakemain.cxx17
-rw-r--r--Source/cmcldeps.cxx1
-rw-r--r--Source/cmcmd.cxx51
-rw-r--r--Source/kwsys/Directory.cxx39
-rw-r--r--Source/kwsys/SystemTools.cxx103
-rw-r--r--Templates/MSBuild/FlagTables/v10_Cuda.json112
-rw-r--r--Tests/Assembler/CMakeLists.txt6
-rw-r--r--Tests/CMakeLib/testArgumentParser.cxx340
-rw-r--r--Tests/CMakeLib/testCMExtEnumSet.cxx9
-rw-r--r--Tests/CMakeLists.txt123
-rw-r--r--Tests/CMakeOnly/AllFindModules/CMakeLists.txt13
-rw-r--r--Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in89
-rw-r--r--Tests/CTestCoverageCollectGCOV/test.cmake.in5
-rw-r--r--Tests/CTestTestFdSetSize/sleep.c14
-rw-r--r--Tests/CompileFeatures/CMakeLists.txt1
-rw-r--r--Tests/CompileFeatures/genex_test.cpp3
-rw-r--r--Tests/Complex/CMakeLists.txt8
-rw-r--r--Tests/Complex/Executable/complex.cxx2
-rw-r--r--Tests/ComplexOneConfig/CMakeLists.txt8
-rw-r--r--Tests/ComplexOneConfig/Executable/complex.cxx2
-rw-r--r--Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt5
-rw-r--r--Tests/CudaOnly/CMakeLists.txt26
-rw-r--r--Tests/CudaOnly/DeviceLTO/CMakeLists.txt37
-rw-r--r--Tests/CudaOnly/DeviceLTO/file1.cu17
-rw-r--r--Tests/CudaOnly/DeviceLTO/file2.cu5
-rw-r--r--Tests/CudaOnly/DeviceLTO/file3.cu4
-rw-r--r--Tests/CudaOnly/DeviceLTO/main.cu62
-rw-r--r--Tests/CudaOnly/ToolkitIsSystemInclude/CMakeLists.txt7
-rw-r--r--Tests/CudaOnly/ToolkitIsSystemInclude/include/nvrtc.h5
-rw-r--r--Tests/CudaOnly/ToolkitIsSystemInclude/main.cu4
-rw-r--r--Tests/ExportImport/Export/CMakeLists.txt11
-rw-r--r--Tests/ExportImport/Import/A/CMakeLists.txt14
-rw-r--r--Tests/ExternalProject/CMakeLists.txt6
-rw-r--r--Tests/FindOpenAL/CMakeLists.txt10
-rw-r--r--Tests/FindOpenAL/Test/CMakeLists.txt14
-rw-r--r--Tests/FindOpenAL/Test/main.cxx13
-rw-r--r--Tests/FindOpenSP/CMakeLists.txt10
-rw-r--r--Tests/FindOpenSP/Test/CMakeLists.txt16
-rw-r--r--Tests/FindOpenSP/Test/main.cxx55
-rw-r--r--Tests/FindOpenSP/Test/test.sgml7
-rw-r--r--Tests/FindPackageTest/CMakeLists.txt2
-rw-r--r--Tests/FindVulkan/Test/CMakeLists.txt20
-rw-r--r--Tests/FindVulkan/Test/Run-dxc_exe.cmake20
-rw-r--r--Tests/FindVulkan/Test/main-dxc_lib.cxx23
-rw-r--r--Tests/FindVulkan/Test/main-volk.cxx14
-rw-r--r--Tests/FortranModules/Submodules/CMakeLists.txt1
-rw-r--r--Tests/FortranModules/Submodules/main.f907
-rw-r--r--Tests/FortranModules/Submodules/obfuscated_parent.f9033
-rw-r--r--Tests/FortranModules/test_module_main.f902
-rw-r--r--Tests/FunctionTest/CMakeLists.txt4
-rw-r--r--Tests/IncludeDirectories/CMakeLists.txt54
-rw-r--r--Tests/LoadCommand/CMakeCommands/cmTestCommand.c17
-rw-r--r--Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c17
-rw-r--r--Tests/Module/CheckIPOSupported-CUDA/CMakeLists.txt32
-rw-r--r--Tests/Module/CheckIPOSupported-CUDA/bar.cu12
-rw-r--r--Tests/Module/CheckIPOSupported-CUDA/foo.cu4
-rw-r--r--Tests/Module/CheckIPOSupported-CUDA/main.cu62
-rw-r--r--Tests/ModuleDefinition/CMakeLists.txt12
-rw-r--r--Tests/Preprocess/CMakeLists.txt7
-rw-r--r--Tests/Preprocess/preprocess.c2
-rw-r--r--Tests/Preprocess/preprocess.cxx2
-rw-r--r--Tests/RunCMake/AutoExportDll/AutoExport.cmake4
-rw-r--r--Tests/RunCMake/CMP0102/CMP0102-OLD-stderr.txt10
-rw-r--r--Tests/RunCMake/CMakeLists.txt13
-rw-r--r--Tests/RunCMake/CMakePresets/Comment-stderr.txt9
-rw-r--r--Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/GoodNoSCache.cmake1
-rw-r--r--Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt5
-rw-r--r--Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt9
-rw-r--r--Tests/RunCMake/CMakePresets/ListAllPresetsNoBuild-stdout.txt8
-rw-r--r--Tests/RunCMake/CMakePresets/ListAllPresetsNoBuild.json.in14
-rw-r--r--Tests/RunCMake/CMakePresets/ListAllPresetsNoTest-stdout.txt8
-rw-r--r--Tests/RunCMake/CMakePresets/ListAllPresetsNoTest.json.in14
-rw-r--r--Tests/RunCMake/CMakePresets/RunCMakeTest.cmake6
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/CMakeLists.txt.in3
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-config-file-check.cmake6
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-configurations-check.cmake18
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-debug-stdout.txt2
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-generators-check.cmake1
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-no-environment-check.cmake7
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-package-directory-check.cmake6
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-package-name-check.cmake7
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-package-version-check.cmake7
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-variables-check.cmake6
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-verbose-stdout.txt1
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good-package-with-environment-check.cmake7
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good.cmake31
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/Good.json.in135
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake101
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-result.txt (renamed from Tests/RunCMake/file-CHMOD/CHMOD-write-only-result.txt)0
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt2
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion.json.in4
-rw-r--r--Tests/RunCMake/CMakePresetsPackage/check.cmake3
-rw-r--r--Tests/RunCMake/CPack/DEB/Helpers.cmake4
-rw-r--r--Tests/RunCMake/CPack/DEB/Prerequirements.cmake6
-rw-r--r--Tests/RunCMake/CPack/RPM/Prerequirements.cmake6
-rw-r--r--Tests/RunCMake/CPack/tests/GENERATE_SHLIBS/DEB-Prerequirements.cmake2
-rw-r--r--Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/DEB-Prerequirements.cmake2
-rw-r--r--Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-Prerequirements.cmake2
-rw-r--r--Tests/RunCMake/CTestTimeout/TestTimeout.c1
-rw-r--r--Tests/RunCMake/CXXModules/CMakeLists.txt6
-rw-r--r--Tests/RunCMake/CXXModules/ExportBuildCxxModules-check.cmake40
-rw-r--r--Tests/RunCMake/CXXModules/ExportBuildCxxModules-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/ExportBuildCxxModules.cmake22
-rw-r--r--Tests/RunCMake/CXXModules/ExportInstallCxxModules-check.cmake35
-rw-r--r--Tests/RunCMake/CXXModules/ExportInstallCxxModules-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/ExportInstallCxxModules.cmake22
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface-result.txt (renamed from Tests/RunCMake/file-CHMOD/CHMOD-no-perms-result.txt)0
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface-stderr.txt12
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface.cmake8
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterfaceImported-stderr.txt6
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterfaceImported.cmake8
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPrivate-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPrivate.cmake13
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPublic-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPublic.cmake13
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesInterface-result.txt (renamed from Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-result.txt)0
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesInterface-stderr.txt12
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesInterface.cmake8
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesInterfaceImported-stderr.txt6
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesInterfaceImported.cmake8
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesPrivate-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesPrivate.cmake12
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesPublic-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/FileSetModulesPublic.cmake12
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMI-check.cmake24
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMI-stderr.txt6
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMI.cmake23
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMIGenericArgs-check.cmake8
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMIGenericArgs-stderr.txt6
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMIGenericArgs.cmake9
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMIIgnore-check.cmake13
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMIIgnore-stderr.txt6
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake9
-rw-r--r--Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake8
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall-check.cmake34
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall.cmake76
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoExport-check.cmake34
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoExport-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoExport.cmake85
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-check.cmake34
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-stderr.txt11
-rw-r--r--Tests/RunCMake/CXXModules/NinjaDependInfoFileSet.cmake59
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX-result.txt (renamed from Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-result.txt)0
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX-stderr.txt20
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX.cmake9
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20-result.txt (renamed from Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-result.txt)0
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20-stderr.txt20
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20.cmake11
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-result.txt (renamed from Tests/RunCMake/file-CHMOD/CHMOD-all-perms-result.txt)0
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt20
-rw-r--r--Tests/RunCMake/CXXModules/NoCXX20ModuleFlag.cmake10
-rw-r--r--Tests/RunCMake/CXXModules/NoDyndepSupport-result.txt1
-rw-r--r--Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt30
-rw-r--r--Tests/RunCMake/CXXModules/NoDyndepSupport.cmake16
-rw-r--r--Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits-result.txt1
-rw-r--r--Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits-stderr.txt22
-rw-r--r--Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits.cmake15
-rw-r--r--Tests/RunCMake/CXXModules/NotCXXSourceModules-result.txt1
-rw-r--r--Tests/RunCMake/CXXModules/NotCXXSourceModules-stderr.txt17
-rw-r--r--Tests/RunCMake/CXXModules/NotCXXSourceModules.cmake13
-rw-r--r--Tests/RunCMake/CXXModules/RunCMakeTest.cmake170
-rw-r--r--Tests/RunCMake/CXXModules/check-json.cmake160
-rw-r--r--Tests/RunCMake/CXXModules/compiler_introspection.cmake25
-rw-r--r--Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi-and-interfaces.cmake22
-rw-r--r--Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake27
-rw-r--r--Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake18
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt66
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx7
-rw-r--r--Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/CMakeLists.txt56
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/forward.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/importable.cxx8
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/private.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt32
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/CMakeLists.txt59
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/forward.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/importable.cxx8
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/private.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt32
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-build-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-build/CMakeLists.txt53
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx8
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt32
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-install-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-install/CMakeLists.txt56
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx8
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt32
-rw-r--r--Tests/RunCMake/CXXModules/examples/generated-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt23
-rw-r--r--Tests/RunCMake/CXXModules/examples/generated/importable.cxx.in5
-rw-r--r--Tests/RunCMake/CXXModules/examples/generated/main.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/CMakeLists.txt27
-rw-r--r--Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/check-for-bmi.cmake7
-rw-r--r--Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/install-bmi-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/install-bmi/CMakeLists.txt25
-rw-r--r--Tests/RunCMake/CXXModules/examples/install-bmi/check-for-bmi.cmake4
-rw-r--r--Tests/RunCMake/CXXModules/examples/install-bmi/importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/internal-partitions-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/internal-partitions/CMakeLists.txt31
-rw-r--r--Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx9
-rw-r--r--Tests/RunCMake/CXXModules/examples/internal-partitions/main.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/internal-partitions/partition.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/library-shared-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/library-static-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/library/CMakeLists.txt30
-rw-r--r--Tests/RunCMake/CXXModules/examples/library/importable.cxx8
-rw-r--r--Tests/RunCMake/CXXModules/examples/library/main.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/partitions-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/partitions/CMakeLists.txt31
-rw-r--r--Tests/RunCMake/CXXModules/examples/partitions/importable.cxx9
-rw-r--r--Tests/RunCMake/CXXModules/examples/partitions/main.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/partitions/partition.cxx8
-rw-r--r--Tests/RunCMake/CXXModules/examples/public-req-private-build-result.txt1
-rw-r--r--Tests/RunCMake/CXXModules/examples/public-req-private-build-stdout.txt1
-rw-r--r--Tests/RunCMake/CXXModules/examples/public-req-private-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/public-req-private/CMakeLists.txt22
-rw-r--r--Tests/RunCMake/CXXModules/examples/public-req-private/priv.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/public-req-private/pub.cxx8
-rw-r--r--Tests/RunCMake/CXXModules/examples/simple-stderr.txt9
-rw-r--r--Tests/RunCMake/CXXModules/examples/simple/CMakeLists.txt18
-rw-r--r--Tests/RunCMake/CXXModules/examples/simple/importable.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/examples/simple/main.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json45
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json45
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json73
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json73
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json40
-rw-r--r--Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json40
-rw-r--r--Tests/RunCMake/CXXModules/sources/c-anchor.c4
-rw-r--r--Tests/RunCMake/CXXModules/sources/cxx-anchor.cxx4
-rw-r--r--Tests/RunCMake/CXXModules/sources/module-header.h9
-rw-r--r--Tests/RunCMake/CXXModules/sources/module-impl.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/sources/module-internal-part-impl.cxx11
-rw-r--r--Tests/RunCMake/CXXModules/sources/module-internal-part.cxx3
-rw-r--r--Tests/RunCMake/CXXModules/sources/module-part-impl.cxx13
-rw-r--r--Tests/RunCMake/CXXModules/sources/module-part.cxx3
-rw-r--r--Tests/RunCMake/CXXModules/sources/module-use.cxx6
-rw-r--r--Tests/RunCMake/CXXModules/sources/module.cxx5
-rw-r--r--Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt4
-rw-r--r--Tests/RunCMake/CommandLine/E_capabilities-stdout.txt2
-rw-r--r--Tests/RunCMake/CommandLine/E_env-equal.cmake15
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-bad-operation-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-bad-operation-stderr.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-cmake_list-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-path_list-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-reset-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-reset-to-unset-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-set-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-string-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-unset-stdout.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-with-double-dash-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-without-double-dash-result.txt1
-rw-r--r--Tests/RunCMake/CommandLine/E_env_modify-without-double-dash-stderr.txt1
-rw-r--r--Tests/RunCMake/CommandLine/RunCMakeTest.cmake58
-rw-r--r--Tests/RunCMake/CommandLine/cmake_depends-stdout.txt2
-rw-r--r--Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/ExternalProject/BUILD_ALWAYS-build1-stdout.txt6
-rw-r--r--Tests/RunCMake/ExternalProject/BUILD_ALWAYS-build2-stdout.txt2
-rw-r--r--Tests/RunCMake/ExternalProject/BUILD_ALWAYS.cmake20
-rw-r--r--Tests/RunCMake/ExternalProject/RunCMakeTest.cmake22
-rw-r--r--Tests/RunCMake/FileAPI/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/FileAPI/ClientStateful-check.py6
-rw-r--r--Tests/RunCMake/FileAPI/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-check.py12
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/fileset.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/subdir.json11
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json32
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json4
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json4
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json6
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json150
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json6
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2.cmake3
-rw-r--r--Tests/RunCMake/FileAPI/subdir/CMakeLists.txt4
-rw-r--r--Tests/RunCMake/FileAPI/subdir/empty.c0
-rw-r--r--Tests/RunCMake/File_Archive/RunCMakeTest.cmake3
-rw-r--r--Tests/RunCMake/File_Archive/create-missing-args-result.txt1
-rw-r--r--Tests/RunCMake/File_Archive/create-missing-args-stderr.txt19
-rw-r--r--Tests/RunCMake/File_Archive/create-missing-args.cmake8
-rw-r--r--Tests/RunCMake/File_Archive/extract-missing-args-result.txt1
-rw-r--r--Tests/RunCMake/File_Archive/extract-missing-args-stderr.txt11
-rw-r--r--Tests/RunCMake/File_Archive/extract-missing-args.cmake5
-rw-r--r--Tests/RunCMake/File_Configure/BadArgContent-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Configure/NoArgContent-result.txt1
-rw-r--r--Tests/RunCMake/File_Configure/NoArgContent-stderr.txt4
-rw-r--r--Tests/RunCMake/File_Configure/NoArgContent.cmake1
-rw-r--r--Tests/RunCMake/File_Configure/NoArgOutput-result.txt1
-rw-r--r--Tests/RunCMake/File_Configure/NoArgOutput-stderr.txt4
-rw-r--r--Tests/RunCMake/File_Configure/NoArgOutput.cmake1
-rw-r--r--Tests/RunCMake/File_Configure/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Generate/InputAndContent-check.cmake8
-rw-r--r--Tests/RunCMake/File_Generate/InputAndContent-input.txt1
-rw-r--r--Tests/RunCMake/File_Generate/InputAndContent.cmake10
-rw-r--r--Tests/RunCMake/File_Generate/NewLineStyle-NoArg-stderr.txt5
-rw-r--r--Tests/RunCMake/File_Generate/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake25
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake28
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/CompileCommands.cmake3
-rw-r--r--Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake1
-rw-r--r--Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake9
-rw-r--r--Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdkDefines-check.cmake64
-rw-r--r--Tests/RunCMake/VsDotnetSdk/VsDotnetSdkDefines.cmake19
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake4
-rw-r--r--Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake4
-rw-r--r--Tests/RunCMake/block/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/block/EndAlone-result.txt1
-rw-r--r--Tests/RunCMake/block/EndAlone-stderr.txt4
-rw-r--r--Tests/RunCMake/block/EndAlone.cmake1
-rw-r--r--Tests/RunCMake/block/EndAloneWithArgument-result.txt1
-rw-r--r--Tests/RunCMake/block/EndAloneWithArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/block/EndAloneWithArgument.cmake1
-rw-r--r--Tests/RunCMake/block/EndMissing-result.txt1
-rw-r--r--Tests/RunCMake/block/EndMissing-stderr.txt4
-rw-r--r--Tests/RunCMake/block/EndMissing.cmake1
-rw-r--r--Tests/RunCMake/block/EndWithArgument-stderr.txt9
-rw-r--r--Tests/RunCMake/block/EndWithArgument.cmake2
-rw-r--r--Tests/RunCMake/block/InvalidArgument-result.txt1
-rw-r--r--Tests/RunCMake/block/InvalidArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/block/InvalidArgument.cmake2
-rw-r--r--Tests/RunCMake/block/InvalidNesting1-result.txt1
-rw-r--r--Tests/RunCMake/block/InvalidNesting1-stderr.txt4
-rw-r--r--Tests/RunCMake/block/InvalidNesting1.cmake6
-rw-r--r--Tests/RunCMake/block/InvalidNesting2-result.txt1
-rw-r--r--Tests/RunCMake/block/InvalidNesting2-stderr.txt4
-rw-r--r--Tests/RunCMake/block/InvalidNesting2.cmake6
-rw-r--r--Tests/RunCMake/block/InvalidNesting3-result.txt1
-rw-r--r--Tests/RunCMake/block/InvalidNesting3-stderr.txt4
-rw-r--r--Tests/RunCMake/block/InvalidNesting3.cmake5
-rw-r--r--Tests/RunCMake/block/InvalidNesting4-result.txt1
-rw-r--r--Tests/RunCMake/block/InvalidNesting4-stderr.txt4
-rw-r--r--Tests/RunCMake/block/InvalidNesting4.cmake5
-rw-r--r--Tests/RunCMake/block/InvalidNesting5-result.txt1
-rw-r--r--Tests/RunCMake/block/InvalidNesting5-stderr.txt4
-rw-r--r--Tests/RunCMake/block/InvalidNesting5.cmake5
-rw-r--r--Tests/RunCMake/block/InvalidNesting6-result.txt1
-rw-r--r--Tests/RunCMake/block/InvalidNesting6-stderr.txt4
-rw-r--r--Tests/RunCMake/block/InvalidNesting6.cmake5
-rw-r--r--Tests/RunCMake/block/MissingArgument-result.txt1
-rw-r--r--Tests/RunCMake/block/MissingArgument-stderr.txt7
-rw-r--r--Tests/RunCMake/block/MissingArgument.cmake2
-rw-r--r--Tests/RunCMake/block/RunCMakeTest.cmake22
-rw-r--r--Tests/RunCMake/block/Scope-POLICIES.cmake30
-rw-r--r--Tests/RunCMake/block/Scope-VARIABLES.cmake52
-rw-r--r--Tests/RunCMake/block/Scope.cmake52
-rw-r--r--Tests/RunCMake/block/Workflows.cmake78
-rw-r--r--Tests/RunCMake/block/WrongArgument-result.txt1
-rw-r--r--Tests/RunCMake/block/WrongArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/block/WrongArgument.cmake2
-rw-r--r--Tests/RunCMake/block/WrongScope-result.txt1
-rw-r--r--Tests/RunCMake/block/WrongScope-stderr.txt4
-rw-r--r--Tests/RunCMake/block/WrongScope.cmake2
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Registry_BadQuery2-stderr.txt6
-rw-r--r--Tests/RunCMake/cmake_host_system_information/Registry_BadView1-stderr.txt6
-rw-r--r--Tests/RunCMake/cmake_language/RunCMakeTest.cmake60
-rw-r--r--Tests/RunCMake/cmake_language/get_message_log_level.cmake5
-rw-r--r--Tests/RunCMake/cmake_language/get_message_log_level_cache-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_language/get_message_log_level_cli-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_language/get_message_log_level_cli_and_cache-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_language/get_message_log_level_cli_and_var-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_language/get_message_log_level_none-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_language/get_message_log_level_var-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_language/get_message_log_level_var_and_cache-stdout.txt1
-rw-r--r--Tests/RunCMake/cmake_path/BASE_DIRECTORY-no-arg-stderr.txt4
-rw-r--r--Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-empty-stderr.txt4
-rw-r--r--Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-no-arg-stderr.txt4
-rw-r--r--Tests/RunCMake/cmake_path/RunCMakeTest.cmake11
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop-result.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop.cmake9
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system-result.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system-stdout.txt1
-rw-r--r--Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system.cmake9
-rw-r--r--Tests/RunCMake/ctest_environment/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/execute_process/EchoCommand3-stderr.txt4
-rw-r--r--Tests/RunCMake/execute_process/EncodingMissing-stderr.txt5
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-all-perms-stderr.txt5
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-all-perms.cmake6
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-stderr.txt6
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-invalid-path.cmake4
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-stderr.txt4
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms.cmake5
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-stderr.txt4
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-no-keyword.cmake5
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-no-perms-stderr.txt4
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-no-perms.cmake5
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-ok.cmake5
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-override.cmake6
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-write-only-stderr.txt6
-rw-r--r--Tests/RunCMake/file-CHMOD/CHMOD-write-only.cmake6
-rw-r--r--Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake18
-rw-r--r--Tests/RunCMake/file-CHMOD/all-perms-result.txt1
-rw-r--r--Tests/RunCMake/file-CHMOD/all-perms-stderr.txt4
-rw-r--r--Tests/RunCMake/file-CHMOD/all-perms.cmake3
-rw-r--r--Tests/RunCMake/file-CHMOD/invalid-path-result.txt1
-rw-r--r--Tests/RunCMake/file-CHMOD/invalid-path-stderr.txt6
-rw-r--r--Tests/RunCMake/file-CHMOD/invalid-path.cmake1
-rw-r--r--Tests/RunCMake/file-CHMOD/invalid-perms-result.txt1
-rw-r--r--Tests/RunCMake/file-CHMOD/invalid-perms-stderr.txt3
-rw-r--r--Tests/RunCMake/file-CHMOD/invalid-perms.cmake2
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-dir-perms-result.txt1
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-dir-perms-stderr.txt5
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-dir-perms.cmake2
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-file-perms-result.txt1
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-file-perms-stderr.txt5
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-file-perms.cmake2
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-perms-result.txt1
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-perms-stderr.txt5
-rw-r--r--Tests/RunCMake/file-CHMOD/missing-perms.cmake2
-rw-r--r--Tests/RunCMake/file-CHMOD/no-perms-result.txt1
-rw-r--r--Tests/RunCMake/file-CHMOD/no-perms-stderr.txt3
-rw-r--r--Tests/RunCMake/file-CHMOD/no-perms.cmake2
-rw-r--r--Tests/RunCMake/file-CHMOD/ok.cmake2
-rw-r--r--Tests/RunCMake/file-CHMOD/override.cmake3
-rw-r--r--Tests/RunCMake/file-CHMOD/write-only-result.txt1
-rw-r--r--Tests/RunCMake/file-CHMOD/write-only-stderr.txt6
-rw-r--r--Tests/RunCMake/file-CHMOD/write-only.cmake3
-rw-r--r--Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt20
-rw-r--r--Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt9
-rw-r--r--Tests/RunCMake/file/RunCMakeTest.cmake1
-rw-r--r--Tests/RunCMake/file/TIMESTAMP-stdout.txt1
-rw-r--r--Tests/RunCMake/file/TIMESTAMP.cmake2
-rw-r--r--Tests/RunCMake/find_file/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-no-function-result.txt1
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-no-function-stderr.txt4
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-no-function.cmake2
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-specify-macro-result.txt1
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-specify-macro-stderr.txt4
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-specify-macro.cmake5
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-stderr.txt3
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-stdout.txt3
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-undefined-function-result.txt1
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-undefined-function-stderr.txt4
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR-undefined-function.cmake2
-rw-r--r--Tests/RunCMake/find_file/VALIDATOR.cmake39
-rw-r--r--Tests/RunCMake/find_library/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-no-function-result.txt1
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-no-function-stderr.txt4
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-no-function.cmake2
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-specify-macro-result.txt1
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-specify-macro-stderr.txt4
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-specify-macro.cmake5
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-stderr.txt3
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-stdout.txt3
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-undefined-function-result.txt1
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-undefined-function-stderr.txt4
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR-undefined-function.cmake2
-rw-r--r--Tests/RunCMake/find_library/VALIDATOR.cmake41
-rw-r--r--Tests/RunCMake/find_package/RunCMakeTest.cmake16
-rw-r--r--Tests/RunCMake/find_package/SearchPaths.cmake2
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPaths-1.2.3/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1.2.3/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1.2.3/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1.2.3/share/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1.2.3/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1.2.3/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake0
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix-stderr.txt10
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_cmake-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-stderr.txt14
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg.cmake1
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-stderr.txt12
-rw-r--r--Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake.cmake1
-rw-r--r--Tests/RunCMake/find_path/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-no-function-result.txt1
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-no-function-stderr.txt4
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-no-function.cmake2
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-specify-macro-result.txt1
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-specify-macro-stderr.txt4
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-specify-macro.cmake5
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-stderr.txt3
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-stdout.txt3
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-undefined-function-result.txt1
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-undefined-function-stderr.txt4
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR-undefined-function.cmake2
-rw-r--r--Tests/RunCMake/find_path/VALIDATOR.cmake39
-rw-r--r--Tests/RunCMake/find_program/RunCMakeTest.cmake4
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-no-function-result.txt1
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-no-function-stderr.txt4
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-no-function.cmake2
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-specify-macro-result.txt1
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-specify-macro-stderr.txt4
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-specify-macro.cmake5
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-stderr.txt3
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-stdout.txt3
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-undefined-function-result.txt1
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-undefined-function-stderr.txt4
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR-undefined-function.cmake2
-rw-r--r--Tests/RunCMake/find_program/VALIDATOR.cmake39
-rw-r--r--Tests/RunCMake/project/LanguagesDuplicate-check.cmake10
-rw-r--r--Tests/RunCMake/project/LanguagesDuplicate.cmake11
-rw-r--r--Tests/RunCMake/project/RunCMakeTest.cmake5
-rw-r--r--Tests/RunCMake/return/CMP0140-NEW.cmake13
-rw-r--r--Tests/RunCMake/return/CMP0140-OLD.cmake8
-rw-r--r--Tests/RunCMake/return/CMP0140-WARN-result.txt1
-rw-r--r--Tests/RunCMake/return/CMP0140-WARN-stderr.txt12
-rw-r--r--Tests/RunCMake/return/CMP0140-WARN.cmake8
-rw-r--r--Tests/RunCMake/return/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/return/PropagateFromDirectory.cmake10
-rw-r--r--Tests/RunCMake/return/PropagateFromFunction.cmake142
-rw-r--r--Tests/RunCMake/return/PropagateNothing.cmake2
-rw-r--r--Tests/RunCMake/return/RunCMakeTest.cmake9
-rw-r--r--Tests/RunCMake/return/WrongArgument-result.txt1
-rw-r--r--Tests/RunCMake/return/WrongArgument-stderr.txt4
-rw-r--r--Tests/RunCMake/return/WrongArgument.cmake2
-rw-r--r--Tests/RunCMake/return/subdir/CMakeLists.txt5
-rw-r--r--Tests/RunCMake/string/JSON.cmake6
-rw-r--r--Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-stderr.txt10
-rw-r--r--Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental-result.txt1
-rw-r--r--Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental-stderr.txt12
-rw-r--r--Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake6
-rw-r--r--Tests/RunCMake/target_sources/FileSetWrongTypeExperimental-result.txt1
-rw-r--r--Tests/RunCMake/target_sources/FileSetWrongTypeExperimental-stderr.txt12
-rw-r--r--Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake6
-rw-r--r--Tests/RunCMake/target_sources/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/BadLinkLibraries.cmake6
-rw-r--r--Tests/RunCMake/try_compile/BadSources1-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/BadSources1.cmake4
-rw-r--r--Tests/RunCMake/try_compile/BadSources2-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/BadSources2.cmake7
-rw-r--r--Tests/RunCMake/try_compile/BinDirEmpty-result.txt1
-rw-r--r--Tests/RunCMake/try_compile/BinDirEmpty-stderr.txt4
-rw-r--r--Tests/RunCMake/try_compile/BinDirEmpty.cmake1
-rw-r--r--Tests/RunCMake/try_compile/BinDirRelative-result.txt1
-rw-r--r--Tests/RunCMake/try_compile/BinDirRelative-stderr.txt6
-rw-r--r--Tests/RunCMake/try_compile/BinDirRelative.cmake1
-rw-r--r--Tests/RunCMake/try_compile/CStandard-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/CStandard.cmake8
-rw-r--r--Tests/RunCMake/try_compile/CStandardGNU.cmake15
-rw-r--r--Tests/RunCMake/try_compile/CStandardNoDefault.cmake8
-rw-r--r--Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile.cmake4
-rw-r--r--Tests/RunCMake/try_compile/CudaStandard-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/CudaStandard.cmake8
-rw-r--r--Tests/RunCMake/try_compile/CxxStandard-stderr.txt15
-rw-r--r--Tests/RunCMake/try_compile/CxxStandard.cmake8
-rw-r--r--Tests/RunCMake/try_compile/CxxStandardGNU.cmake15
-rw-r--r--Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake8
-rw-r--r--Tests/RunCMake/try_compile/EmptyListArgs.cmake11
-rw-r--r--Tests/RunCMake/try_compile/EmptyValueArgs-result.txt1
-rw-r--r--Tests/RunCMake/try_compile/EmptyValueArgs-stderr.txt9
-rw-r--r--Tests/RunCMake/try_compile/EmptyValueArgs.cmake7
-rw-r--r--Tests/RunCMake/try_compile/EnvConfig.cmake6
-rw-r--r--Tests/RunCMake/try_compile/ISPCDuplicateTarget.cmake12
-rw-r--r--Tests/RunCMake/try_compile/ISPCDuplicateTargetNinja.cmake13
-rw-r--r--Tests/RunCMake/try_compile/ISPCInvalidTarget.cmake9
-rw-r--r--Tests/RunCMake/try_compile/ISPCTargets.cmake9
-rw-r--r--Tests/RunCMake/try_compile/NoArgs-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/NoCStandard-result.txt1
-rw-r--r--Tests/RunCMake/try_compile/NoCStandard-stderr.txt7
-rw-r--r--Tests/RunCMake/try_compile/NoCStandard.cmake4
-rw-r--r--Tests/RunCMake/try_compile/NoCopyFile-stderr.txt7
-rw-r--r--Tests/RunCMake/try_compile/NoCopyFile.cmake4
-rw-r--r--Tests/RunCMake/try_compile/NoCopyFile2-stderr.txt7
-rw-r--r--Tests/RunCMake/try_compile/NoCopyFile2.cmake4
-rw-r--r--Tests/RunCMake/try_compile/NoCopyFileError-stderr.txt7
-rw-r--r--Tests/RunCMake/try_compile/NoCopyFileError.cmake4
-rw-r--r--Tests/RunCMake/try_compile/NoOutputVariable-stderr.txt7
-rw-r--r--Tests/RunCMake/try_compile/NoOutputVariable.cmake4
-rw-r--r--Tests/RunCMake/try_compile/NoOutputVariable2-stderr.txt7
-rw-r--r--Tests/RunCMake/try_compile/NoOutputVariable2.cmake4
-rw-r--r--Tests/RunCMake/try_compile/NoSources-stderr.txt7
-rw-r--r--Tests/RunCMake/try_compile/NonSourceCompileDefinitions-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/NonSourceCopyFile-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/ObjCStandard-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/ObjCStandard.cmake8
-rw-r--r--Tests/RunCMake/try_compile/ObjCxxStandard-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/ObjCxxStandard.cmake8
-rw-r--r--Tests/RunCMake/try_compile/OneArg-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/RunCMakeTest.cmake61
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeExe.cmake10
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeInvalid.cmake6
-rw-r--r--Tests/RunCMake/try_compile/TargetTypeStatic.cmake10
-rw-r--r--Tests/RunCMake/try_compile/TryRunArgs-stderr.txt18
-rw-r--r--Tests/RunCMake/try_compile/TryRunArgs.cmake14
-rw-r--r--Tests/RunCMake/try_compile/TwoArgs-stderr.txt2
-rw-r--r--Tests/RunCMake/try_compile/new_signature.cmake2
-rw-r--r--Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake54
-rw-r--r--Tests/RunCMake/try_compile/old_signature.cmake2
-rw-r--r--Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt2
-rw-r--r--Tests/RunCMake/try_run/BadLinkLibraries.cmake7
-rw-r--r--Tests/RunCMake/try_run/BinDirEmpty-result.txt1
-rw-r--r--Tests/RunCMake/try_run/BinDirEmpty-stderr.txt4
-rw-r--r--Tests/RunCMake/try_run/BinDirEmpty.cmake1
-rw-r--r--Tests/RunCMake/try_run/BinDirRelative-result.txt1
-rw-r--r--Tests/RunCMake/try_run/BinDirRelative-stderr.txt6
-rw-r--r--Tests/RunCMake/try_run/BinDirRelative.cmake1
-rw-r--r--Tests/RunCMake/try_run/NoCompileOutputVariable-result.txt1
-rw-r--r--Tests/RunCMake/try_run/NoCompileOutputVariable-stderr.txt7
-rw-r--r--Tests/RunCMake/try_run/NoCompileOutputVariable.cmake6
-rw-r--r--Tests/RunCMake/try_run/NoOutputCompileVariable-result.txt1
-rw-r--r--Tests/RunCMake/try_run/NoOutputVariable-result.txt1
-rw-r--r--Tests/RunCMake/try_run/NoOutputVariable-stderr.txt7
-rw-r--r--Tests/RunCMake/try_run/NoOutputVariable.cmake4
-rw-r--r--Tests/RunCMake/try_run/NoRunOutputVariable-result.txt1
-rw-r--r--Tests/RunCMake/try_run/NoRunOutputVariable-stderr.txt7
-rw-r--r--Tests/RunCMake/try_run/NoRunOutputVariable.cmake6
-rw-r--r--Tests/RunCMake/try_run/NoRunStdErrVariable-result.txt1
-rw-r--r--Tests/RunCMake/try_run/NoRunStdErrVariable-stderr.txt7
-rw-r--r--Tests/RunCMake/try_run/NoRunStdErrVariable.cmake7
-rw-r--r--Tests/RunCMake/try_run/NoRunStdOutVariable-result.txt1
-rw-r--r--Tests/RunCMake/try_run/NoRunStdOutVariable-stderr.txt7
-rw-r--r--Tests/RunCMake/try_run/NoRunStdOutVariable.cmake7
-rw-r--r--Tests/RunCMake/try_run/NoWorkingDirectory-result.txt1
-rw-r--r--Tests/RunCMake/try_run/NoWorkingDirectory-stderr.txt7
-rw-r--r--Tests/RunCMake/try_run/NoWorkingDirectory.cmake6
-rw-r--r--Tests/RunCMake/try_run/RunCMakeTest.cmake14
-rw-r--r--Tests/RunCMake/try_run/WorkingDirArg.cmake8
-rw-r--r--Tests/RunCMake/try_run/new_signature.cmake2
-rw-r--r--Tests/RunCMake/try_run/old_and_new_signature_tests.cmake11
-rw-r--r--Tests/RunCMake/try_run/old_signature.cmake2
-rw-r--r--Tests/SwiftOnly/CMakeLists.txt1
-rw-r--r--Tests/SwiftOnly/main.swift6
-rw-r--r--Tests/TryCompile/CMakeLists.txt282
-rw-r--r--Tests/TryCompile/old_and_new_signature_tests.cmake245
-rw-r--r--Tests/TryCompile/stdout_and_stderr.c8
-rw-r--r--Utilities/Doxygen/CMakeLists.txt2
-rw-r--r--Utilities/IWYU/mapping.imp2
-rw-r--r--Utilities/Release/WiX/CustomAction/CMakeLists.txt4
-rw-r--r--Utilities/Release/linux/aarch64/Dockerfile2
-rw-r--r--Utilities/Release/linux/x86_64/Dockerfile2
-rw-r--r--Utilities/Sphinx/CMakeLists.txt6
-rw-r--r--Utilities/cmcurl/CMakeLists.txt2
-rw-r--r--Utilities/cmcurl/lib/vtls/openssl.c24
-rw-r--r--Utilities/std/cmext/enum_set13
-rwxr-xr-xbootstrap4
1160 files changed, 19607 insertions, 5707 deletions
diff --git a/.gitignore b/.gitignore
index 5bd9113..f57271f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@ out/
# Visual Studio Code
.vscode/
+.cache/
# CLion work directory
.idea/
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 65bcd5f..fa11b15 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -275,6 +275,26 @@ t:hip4.2-radeon:
variables:
CMAKE_CI_NO_MR: "true"
+t:linux-gcc-cxx-modules-ninja:
+ extends:
+ - .gcc_cxx_modules_ninja
+ - .cmake_test_linux_release
+ - .linux_builder_tags
+ - .run_dependent
+ - .needs_centos6_x86_64
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+t:linux-gcc-cxx-modules-ninja-multi:
+ extends:
+ - .gcc_cxx_modules_ninja_multi
+ - .cmake_test_linux_release
+ - .linux_builder_tags
+ - .run_dependent
+ - .needs_centos6_x86_64
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
b:fedora36-ninja:
extends:
- .fedora36_ninja
@@ -294,6 +314,33 @@ b:debian10-makefiles-inplace:
variables:
CMAKE_CI_JOB_NIGHTLY: "true"
+b:debian10-extdeps:
+ extends:
+ - .debian10_extdeps
+ - .cmake_build_linux_standalone
+ - .linux_builder_tags
+ - .run_manually
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+b:debian10-aarch64-extdeps:
+ extends:
+ - .debian10_aarch64_extdeps
+ - .cmake_build_linux_standalone
+ - .linux_builder_tags_aarch64
+ - .run_manually
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
+b:fedora36-extdeps:
+ extends:
+ - .fedora36_extdeps
+ - .cmake_build_linux_standalone
+ - .linux_builder_tags
+ - .run_manually
+ variables:
+ CMAKE_CI_JOB_NIGHTLY: "true"
+
t:fedora36-ninja:
extends:
- .fedora36_ninja
diff --git a/.gitlab/ci/configure_debian10_aarch64_extdeps.cmake b/.gitlab/ci/configure_debian10_aarch64_extdeps.cmake
new file mode 100644
index 0000000..8e545f5
--- /dev/null
+++ b/.gitlab/ci/configure_debian10_aarch64_extdeps.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_extdeps_common.cmake")
diff --git a/.gitlab/ci/configure_debian10_aarch64_ninja.cmake b/.gitlab/ci/configure_debian10_aarch64_ninja.cmake
index bbccbcf..605f6ba 100644
--- a/.gitlab/ci/configure_debian10_aarch64_ninja.cmake
+++ b/.gitlab/ci/configure_debian10_aarch64_ninja.cmake
@@ -44,11 +44,13 @@ set(CMake_TEST_FindMPI_Fortran "ON" CACHE BOOL "")
set(CMake_TEST_FindMPI "ON" CACHE BOOL "")
set(CMake_TEST_FindODBC "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenACC "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenAL "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenGL "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_Fortran "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenSP "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenSSL "ON" CACHE BOOL "")
set(CMake_TEST_FindPatch "ON" CACHE BOOL "")
set(CMake_TEST_FindPNG "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_debian10_extdeps.cmake b/.gitlab/ci/configure_debian10_extdeps.cmake
new file mode 100644
index 0000000..8e545f5
--- /dev/null
+++ b/.gitlab/ci/configure_debian10_extdeps.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_extdeps_common.cmake")
diff --git a/.gitlab/ci/configure_debian10_ninja.cmake b/.gitlab/ci/configure_debian10_ninja.cmake
index 2fcff7a..214828a 100644
--- a/.gitlab/ci/configure_debian10_ninja.cmake
+++ b/.gitlab/ci/configure_debian10_ninja.cmake
@@ -48,11 +48,13 @@ set(CMake_TEST_FindMPI_Fortran "ON" CACHE BOOL "")
set(CMake_TEST_FindMPI "ON" CACHE BOOL "")
set(CMake_TEST_FindODBC "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenACC "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenAL "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenGL "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_Fortran "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenSP "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenSSL "ON" CACHE BOOL "")
set(CMake_TEST_FindPatch "ON" CACHE BOOL "")
set(CMake_TEST_FindPNG "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_extdeps_common.cmake b/.gitlab/ci/configure_extdeps_common.cmake
new file mode 100644
index 0000000..2c7d328
--- /dev/null
+++ b/.gitlab/ci/configure_extdeps_common.cmake
@@ -0,0 +1,5 @@
+set(CMAKE_USE_SYSTEM_LIBRARIES ON CACHE BOOL "")
+set(CMAKE_SKIP_BOOTSTRAP_TEST ON CACHE BOOL "")
+set(CMake_TEST_Qt6 OFF CACHE BOOL "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_common.cmake")
diff --git a/.gitlab/ci/configure_fedora36_extdeps.cmake b/.gitlab/ci/configure_fedora36_extdeps.cmake
new file mode 100644
index 0000000..8e545f5
--- /dev/null
+++ b/.gitlab/ci/configure_fedora36_extdeps.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_LIST_DIR}/configure_extdeps_common.cmake")
diff --git a/.gitlab/ci/configure_fedora36_makefiles.cmake b/.gitlab/ci/configure_fedora36_makefiles.cmake
index c5b5190..11d1a08 100644
--- a/.gitlab/ci/configure_fedora36_makefiles.cmake
+++ b/.gitlab/ci/configure_fedora36_makefiles.cmake
@@ -47,11 +47,13 @@ set(CMake_TEST_FindMPI_Fortran "ON" CACHE BOOL "")
set(CMake_TEST_FindMPI "ON" CACHE BOOL "")
set(CMake_TEST_FindODBC "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenACC "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenAL "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenGL "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_C "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_CXX "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP_Fortran "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenMP "ON" CACHE BOOL "")
+set(CMake_TEST_FindOpenSP "ON" CACHE BOOL "")
set(CMake_TEST_FindOpenSSL "ON" CACHE BOOL "")
set(CMake_TEST_FindPatch "ON" CACHE BOOL "")
set(CMake_TEST_FindPNG "ON" CACHE BOOL "")
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake
new file mode 100644
index 0000000..2b04e89
--- /dev/null
+++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja.cmake
@@ -0,0 +1,4 @@
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake
new file mode 100644
index 0000000..2b04e89
--- /dev/null
+++ b/.gitlab/ci/configure_linux_gcc_cxx_modules_ninja_multi.cmake
@@ -0,0 +1,4 @@
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_gcc.cmake" CACHE STRING "")
+
+include("${CMAKE_CURRENT_LIST_DIR}/configure_external_test.cmake")
diff --git a/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake b/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake
new file mode 100644
index 0000000..8570196
--- /dev/null
+++ b/.gitlab/ci/configure_windows_msvc_cxx_modules_common.cmake
@@ -0,0 +1,2 @@
+set(CMake_TEST_MODULE_COMPILATION "named,partitions,internal_partitions,shared,export_bmi,install_bmi" CACHE STRING "")
+set(CMake_TEST_MODULE_COMPILATION_RULES "${CMAKE_CURRENT_LIST_DIR}/cxx_modules_rules_msvc.cmake" CACHE STRING "")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake b/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake
index 7f57181..f5a6d80 100644
--- a/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake
+++ b/.gitlab/ci/configure_windows_vs2022_x64_ninja.cmake
@@ -2,4 +2,5 @@ if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
set(CMake_TEST_ISPC "ON" CACHE STRING "")
endif()
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_cxx_modules_common.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_vs_common_ninja.cmake")
diff --git a/.gitlab/ci/configure_windows_vs2022_x64_ninja_multi.cmake b/.gitlab/ci/configure_windows_vs2022_x64_ninja_multi.cmake
index 5b2f0b7..2b0c76d 100644
--- a/.gitlab/ci/configure_windows_vs2022_x64_ninja_multi.cmake
+++ b/.gitlab/ci/configure_windows_vs2022_x64_ninja_multi.cmake
@@ -2,4 +2,5 @@ if (NOT "$ENV{CMAKE_CI_NIGHTLY}" STREQUAL "")
set(CMake_TEST_ISPC "ON" CACHE STRING "")
endif()
+include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_cxx_modules_common.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/configure_windows_msvc_common.cmake")
diff --git a/.gitlab/ci/ctest_standalone.cmake b/.gitlab/ci/ctest_standalone.cmake
index 9199693..36ba71c 100644
--- a/.gitlab/ci/ctest_standalone.cmake
+++ b/.gitlab/ci/ctest_standalone.cmake
@@ -3,8 +3,8 @@ cmake_minimum_required(VERSION 3.8)
include("${CMAKE_CURRENT_LIST_DIR}/gitlab_ci.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/env_$ENV{CMAKE_CONFIGURATION}.cmake" OPTIONAL)
-set(cmake_args
- -C "${CMAKE_CURRENT_LIST_DIR}/configure_$ENV{CMAKE_CONFIGURATION}.cmake")
+set(initial_cache "${CMAKE_CURRENT_LIST_DIR}/configure_$ENV{CMAKE_CONFIGURATION}.cmake")
+set(cmake_args -C "${initial_cache}")
include(ProcessorCount)
ProcessorCount(nproc)
@@ -25,6 +25,8 @@ ctest_update()
if("$ENV{CMAKE_CI_BOOTSTRAP}")
set(CTEST_CONFIGURE_COMMAND "\"${CTEST_SOURCE_DIRECTORY}/bootstrap\" --parallel=${nproc}")
+elseif("$ENV{CMAKE_CONFIGURATION}" MATCHES "extdeps")
+ set(CTEST_CONFIGURE_COMMAND "/opt/extdeps/bin/cmake -C \"${initial_cache}\" -G \"${CTEST_CMAKE_GENERATOR}\" \"${CTEST_SOURCE_DIRECTORY}\"")
endif()
# Configure the project.
diff --git a/.gitlab/ci/cxx_modules_rules_gcc.cmake b/.gitlab/ci/cxx_modules_rules_gcc.cmake
new file mode 100644
index 0000000..d800099
--- /dev/null
+++ b/.gitlab/ci/cxx_modules_rules_gcc.cmake
@@ -0,0 +1,10 @@
+set(CMake_TEST_CXXModules_UUID "a246741c-d067-4019-a8fb-3d16b0c9d1d3")
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
+ "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E -x c++ <SOURCE>"
+ " -MT <DYNDEP_FILE> -MD -MF <DEP_FILE>"
+ " -fmodules-ts -fdep-file=<DYNDEP_FILE> -fdep-output=<OBJECT> -fdep-format=trtbd"
+ " -o <PREPROCESSED_SOURCE>")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "gcc")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "-fmodules-ts -fmodule-mapper=<MODULE_MAP_FILE> -fdep-format=trtbd -x c++")
diff --git a/.gitlab/ci/cxx_modules_rules_msvc.cmake b/.gitlab/ci/cxx_modules_rules_msvc.cmake
new file mode 100644
index 0000000..5f0ae76
--- /dev/null
+++ b/.gitlab/ci/cxx_modules_rules_msvc.cmake
@@ -0,0 +1,11 @@
+set(CMake_TEST_CXXModules_UUID "a246741c-d067-4019-a8fb-3d16b0c9d1d3")
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+string(CONCAT CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE
+ "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> <SOURCE> -nologo -TP"
+ " -showIncludes"
+ " -scanDependencies <DYNDEP_FILE>"
+ " -Fo<OBJECT>")
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT "msvc")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FORMAT "msvc")
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_MAP_FLAG "@<MODULE_MAP_FILE>")
diff --git a/.gitlab/ci/docker/debian10-aarch64/install_deps.sh b/.gitlab/ci/docker/debian10-aarch64/install_deps.sh
index 3dd814d..8b5a001 100755
--- a/.gitlab/ci/docker/debian10-aarch64/install_deps.sh
+++ b/.gitlab/ci/docker/debian10-aarch64/install_deps.sh
@@ -14,6 +14,20 @@ apt-get install -y \
curl \
git
+# Install optional external build dependencies.
+apt-get install -y \
+ libarchive-dev \
+ libbz2-dev \
+ libcurl4-gnutls-dev \
+ libexpat1-dev \
+ libjsoncpp-dev \
+ liblzma-dev \
+ libncurses-dev \
+ librhash-dev \
+ libuv1-dev \
+ libzstd-dev \
+ zlib1g-dev
+
# Install iwyu runtime deps.
apt-get install -y \
clang-6.0 \
@@ -66,6 +80,7 @@ apt-get install -y \
liblzma-dev \
libopenal-dev \
libopenmpi-dev openmpi-bin \
+ libosp-dev \
libpng-dev \
libpq-dev postgresql-server-dev-11 \
libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc \
diff --git a/.gitlab/ci/docker/debian10/install_deps.sh b/.gitlab/ci/docker/debian10/install_deps.sh
index f796816..486b2f7 100755
--- a/.gitlab/ci/docker/debian10/install_deps.sh
+++ b/.gitlab/ci/docker/debian10/install_deps.sh
@@ -14,6 +14,20 @@ apt-get install -y \
curl \
git
+# Install optional external build dependencies.
+apt-get install -y \
+ libarchive-dev \
+ libbz2-dev \
+ libcurl4-gnutls-dev \
+ libexpat1-dev \
+ libjsoncpp-dev \
+ liblzma-dev \
+ libncurses-dev \
+ librhash-dev \
+ libuv1-dev \
+ libzstd-dev \
+ zlib1g-dev
+
# Install iwyu runtime deps.
apt-get install -y \
clang-6.0 \
@@ -70,6 +84,7 @@ apt-get install -y \
liblzma-dev \
libopenal-dev \
libopenmpi-dev openmpi-bin \
+ libosp-dev \
libpng-dev \
libpq-dev postgresql-server-dev-11 \
libprotobuf-dev libprotobuf-c-dev libprotoc-dev protobuf-compiler protobuf-compiler-grpc \
diff --git a/.gitlab/ci/docker/fedora36/Dockerfile b/.gitlab/ci/docker/fedora36/Dockerfile
index 26f8e3e..299d48a 100644
--- a/.gitlab/ci/docker/fedora36/Dockerfile
+++ b/.gitlab/ci/docker/fedora36/Dockerfile
@@ -4,6 +4,12 @@ MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
COPY install_rvm.sh /root/install_rvm.sh
RUN sh /root/install_rvm.sh
+FROM fedora:36 AS clang-tidy-headers
+MAINTAINER Kyle Edwards <kyle.edwards@kitware.com>
+
+COPY install_clang_tidy_headers.sh /root/install_clang_tidy_headers.sh
+RUN sh /root/install_clang_tidy_headers.sh
+
FROM fedora:36
MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
@@ -13,3 +19,6 @@ RUN sh /root/install_deps.sh
COPY --from=rvm-build /root/rvm.tar /root/rvm.tar
RUN tar -C /usr/local -xf /root/rvm.tar \
&& rm /root/rvm.tar
+COPY --from=clang-tidy-headers /root/clang-tidy-headers.tar /root/clang-tidy-headers.tar
+RUN tar -C /usr/include -xf /root/clang-tidy-headers.tar \
+ && rm /root/clang-tidy-headers.tar
diff --git a/.gitlab/ci/docker/fedora36/install_clang_tidy_headers.sh b/.gitlab/ci/docker/fedora36/install_clang_tidy_headers.sh
new file mode 100755
index 0000000..b9883f4
--- /dev/null
+++ b/.gitlab/ci/docker/fedora36/install_clang_tidy_headers.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+set -e
+
+# Packages for building the clang-tidy plugin.
+# TODO: Upstream this as a proper Fedora package.
+dnf install --setopt=install_weak_deps=False -y \
+ 'dnf-command(download)' \
+ rpm-build \
+ python3-devel \
+ clang-tools-extra
+clang_source_rpm=$(rpm -q --queryformat '%{SOURCERPM}' clang-tools-extra)
+clang_version=$(rpm -q --queryformat '%{VERSION}' clang-tools-extra)
+dnf download --source -y clang
+rpm -i "$clang_source_rpm"
+rpmbuild -bp /root/rpmbuild/SPECS/clang.spec
+cd "/root/rpmbuild/BUILD/clang-tools-extra-$clang_version.src"
+find clang-tidy -name '*.h' | tar -cf /root/clang-tidy-headers.tar -T -
diff --git a/.gitlab/ci/docker/fedora36/install_deps.sh b/.gitlab/ci/docker/fedora36/install_deps.sh
index b8ddfb9..f117888 100755
--- a/.gitlab/ci/docker/fedora36/install_deps.sh
+++ b/.gitlab/ci/docker/fedora36/install_deps.sh
@@ -17,6 +17,20 @@ dnf install --setopt=install_weak_deps=False -y \
git-core \
make
+# Install optional external build dependencies.
+dnf install --setopt=install_weak_deps=False -y \
+ bzip2-devel \
+ expat-devel \
+ jsoncpp-devel \
+ libarchive-devel \
+ libcurl-devel \
+ libuv-devel \
+ libuv-devel \
+ libzstd-devel \
+ rhash-devel \
+ xz-devel \
+ zlib-devel
+
# Install documentation tools.
dnf install --setopt=install_weak_deps=False -y \
python3-sphinx \
@@ -78,6 +92,7 @@ dnf install --setopt=install_weak_deps=False -y \
libinput-devel systemd-devel \
libjpeg-turbo-devel \
libpng-devel \
+ opensp-devel \
postgresql-server-devel \
libtiff-devel \
libuv-devel \
diff --git a/.gitlab/ci/docker/gcc_cxx_modules/Dockerfile b/.gitlab/ci/docker/gcc_cxx_modules/Dockerfile
new file mode 100644
index 0000000..e0af0b9
--- /dev/null
+++ b/.gitlab/ci/docker/gcc_cxx_modules/Dockerfile
@@ -0,0 +1,9 @@
+FROM fedora:36
+MAINTAINER Ben Boeckel <ben.boeckel@kitware.com>
+
+# Install build dependencies for packages.
+COPY install_deps.sh /root/install_deps.sh
+RUN sh /root/install_deps.sh
+
+COPY install_gcc.sh /root/install_gcc.sh
+RUN sh /root/install_gcc.sh
diff --git a/.gitlab/ci/docker/gcc_cxx_modules/install_deps.sh b/.gitlab/ci/docker/gcc_cxx_modules/install_deps.sh
new file mode 100755
index 0000000..b8b706b
--- /dev/null
+++ b/.gitlab/ci/docker/gcc_cxx_modules/install_deps.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+set -e
+
+dnf install -y --setopt=install_weak_deps=False \
+ gcc-c++ mpfr-devel libmpc-devel isl-devel flex bison file findutils diffutils git-core
+dnf clean all
diff --git a/.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh b/.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh
new file mode 100755
index 0000000..20ea35f
--- /dev/null
+++ b/.gitlab/ci/docker/gcc_cxx_modules/install_gcc.sh
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+set -e
+
+readonly revision="p1689r5-cmake-ci-20220614" # 3075e510e3d29583f8886b95aff044c0474c84a5
+readonly tarball="https://github.com/mathstuf/gcc/archive/$revision.tar.gz"
+
+readonly workdir="$HOME/gcc"
+readonly srcdir="$workdir/gcc"
+readonly builddir="$workdir/build"
+readonly njobs="$( nproc )"
+
+mkdir -p "$workdir"
+cd "$workdir"
+curl -L "$tarball" > "gcc-$revision.tar.gz"
+tar xf "gcc-$revision.tar.gz"
+mv "gcc-$revision" "$srcdir"
+mkdir -p "$builddir"
+cd "$builddir"
+"$srcdir/configure" \
+ --disable-multilib \
+ --enable-languages=c,c++ \
+ --prefix="/opt/gcc-p1689"
+make "-j$njobs"
+make "-j$njobs" install-strip
+rm -rf "$workdir"
diff --git a/.gitlab/ci/env_debian10_aarch64_extdeps.sh b/.gitlab/ci/env_debian10_aarch64_extdeps.sh
new file mode 100644
index 0000000..7076e18
--- /dev/null
+++ b/.gitlab/ci/env_debian10_aarch64_extdeps.sh
@@ -0,0 +1 @@
+source .gitlab/ci/env_extdeps_common.sh
diff --git a/.gitlab/ci/env_debian10_extdeps.sh b/.gitlab/ci/env_debian10_extdeps.sh
new file mode 100644
index 0000000..7076e18
--- /dev/null
+++ b/.gitlab/ci/env_debian10_extdeps.sh
@@ -0,0 +1 @@
+source .gitlab/ci/env_extdeps_common.sh
diff --git a/.gitlab/ci/env_extdeps_common.sh b/.gitlab/ci/env_extdeps_common.sh
new file mode 100644
index 0000000..8cabc05
--- /dev/null
+++ b/.gitlab/ci/env_extdeps_common.sh
@@ -0,0 +1,5 @@
+.gitlab/ci/extdeps-linux.sh
+
+export CMAKE_PREFIX_PATH=/opt/extdeps
+export PATH=/opt/extdeps/bin:$PATH
+export LD_LIBRARY_PATH=/opt/extdeps/lib
diff --git a/.gitlab/ci/env_fedora36_extdeps.sh b/.gitlab/ci/env_fedora36_extdeps.sh
new file mode 100644
index 0000000..7076e18
--- /dev/null
+++ b/.gitlab/ci/env_fedora36_extdeps.sh
@@ -0,0 +1 @@
+source .gitlab/ci/env_extdeps_common.sh
diff --git a/.gitlab/ci/extdeps-linux.sh b/.gitlab/ci/extdeps-linux.sh
new file mode 100755
index 0000000..f0d4c0d
--- /dev/null
+++ b/.gitlab/ci/extdeps-linux.sh
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+set -e
+
+mkdir -p /opt/extdeps/src
+cd /opt/extdeps/src
+export PATH=/opt/extdeps/bin:$PATH
+
+#----------------------------------------------------------------------------
+# cmake
+
+case "$(uname -s)-$(uname -m)" in
+ Linux-x86_64)
+ cmake_version="3.13.5"
+ cmake_sha256sum="e2fd0080a6f0fc1ec84647acdcd8e0b4019770f48d83509e6a5b0b6ea27e5864"
+ cmake_platform="Linux-x86_64"
+ ;;
+ Linux-aarch64)
+ cmake_version="3.19.8"
+ cmake_sha256sum="807f5afb2a560e00af9640e496d5673afefc2888bf0ed076412884a5ebb547a1"
+ cmake_platform="Linux-aarch64"
+ ;;
+ *)
+ echo "Unrecognized platform $(uname -s)-$(uname -m)"
+ exit 1
+ ;;
+esac
+readonly shatool
+readonly cmake_sha256sum
+readonly cmake_platform
+
+readonly cmake_filename="cmake-$cmake_version-$cmake_platform"
+readonly cmake_tarball="$cmake_filename.tar.gz"
+
+echo "$cmake_sha256sum $cmake_tarball" > cmake.sha256sum
+curl -OL "https://github.com/Kitware/CMake/releases/download/v$cmake_version/$cmake_tarball"
+sha256sum --check cmake.sha256sum
+tar xzf "$cmake_tarball" -C /opt/extdeps --strip-components=1
+rm -f "$cmake_tarball" cmake.sha256sum
+
+#----------------------------------------------------------------------------
+# libuv
+
+curl -L -o libuv-1.28.0.tar.gz https://github.com/libuv/libuv/archive/refs/tags/v1.28.0.tar.gz
+tar xzf libuv-1.28.0.tar.gz
+cmake -S libuv-1.28.0 -B libuv-1.28.0-build \
+ -DCMAKE_INSTALL_PREFIX=/opt/extdeps
+cmake --build libuv-1.28.0-build --target install
+rm -rf libuv-1.28.0*
+
+#----------------------------------------------------------------------------
+# jsoncpp
+
+curl -L -o jsoncpp-1.6.0.tar.gz https://github.com/open-source-parsers/jsoncpp/archive/refs/tags/1.6.0.tar.gz
+tar xzf jsoncpp-1.6.0.tar.gz
+cmake -S jsoncpp-1.6.0 -B jsoncpp-1.6.0-build \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DJSONCPP_LIB_BUILD_STATIC=ON \
+ -DJSONCPP_LIB_BUILD_SHARED=ON \
+ -DCMAKE_INSTALL_PREFIX=/opt/extdeps
+cmake --build jsoncpp-1.6.0-build --target install
+rm -rf jsoncpp-1.6.0*
diff --git a/.gitlab/os-linux.yml b/.gitlab/os-linux.yml
index 12fbc1e..a46ec22 100644
--- a/.gitlab/os-linux.yml
+++ b/.gitlab/os-linux.yml
@@ -45,7 +45,7 @@
### Debian
.debian10:
- image: "kitware/cmake:ci-debian10-x86_64-2022-06-21"
+ image: "kitware/cmake:ci-debian10-x86_64-2022-08-30"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
@@ -60,7 +60,7 @@
CMAKE_CI_NO_INSTALL: 1
.debian10_aarch64:
- image: "kitware/cmake:ci-debian10-aarch64-2022-06-21"
+ image: "kitware/cmake:ci-debian10-aarch64-2022-08-30"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
@@ -69,7 +69,7 @@
### Fedora
.fedora36:
- image: "kitware/cmake:ci-fedora36-x86_64-2022-06-21"
+ image: "kitware/cmake:ci-fedora36-x86_64-2022-08-31"
variables:
GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci/long file name for testing purposes"
@@ -137,6 +137,30 @@
CMAKE_CI_NO_INSTALL: 1
CTEST_NO_WARNINGS_ALLOWED: 1
+.debian10_extdeps:
+ extends: .debian10
+
+ variables:
+ CMAKE_CONFIGURATION: debian10_extdeps
+ CMAKE_CI_BUILD_TYPE: Release
+ CTEST_NO_WARNINGS_ALLOWED: 1
+
+.debian10_aarch64_extdeps:
+ extends: .debian10_aarch64
+
+ variables:
+ CMAKE_CONFIGURATION: debian10_aarch64_extdeps
+ CMAKE_CI_BUILD_TYPE: Release
+ CTEST_NO_WARNINGS_ALLOWED: 1
+
+.fedora36_extdeps:
+ extends: .fedora36
+
+ variables:
+ CMAKE_CONFIGURATION: fedora36_extdeps
+ CMAKE_CI_BUILD_TYPE: Release
+ CTEST_NO_WARNINGS_ALLOWED: 1
+
.fedora36_ninja:
extends: .fedora36
@@ -299,6 +323,30 @@
CMAKE_CONFIGURATION: hip4.2_radeon
CMAKE_GENERATOR: "Ninja Multi-Config"
+### C++ modules
+
+.gcc_cxx_modules_x86_64:
+ image: "kitware/cmake:ci-gcc_cxx_modules-x86_64-2022-06-21"
+
+ variables:
+ GIT_CLONE_PATH: "$CI_BUILDS_DIR/cmake ci"
+ CMAKE_ARCH: x86_64
+ CC: "/opt/gcc-p1689/bin/gcc"
+ CXX: "/opt/gcc-p1689/bin/g++"
+
+.gcc_cxx_modules_ninja:
+ extends: .gcc_cxx_modules_x86_64
+
+ variables:
+ CMAKE_CONFIGURATION: linux_gcc_cxx_modules_ninja
+
+.gcc_cxx_modules_ninja_multi:
+ extends: .gcc_cxx_modules_x86_64
+
+ variables:
+ CMAKE_CONFIGURATION: linux_gcc_cxx_modules_ninja_multi
+ CMAKE_GENERATOR: "Ninja Multi-Config"
+
## Tags
.linux_builder_tags:
@@ -457,7 +505,7 @@
# use the scripts here.
- "$LAUNCHER make -j$(nproc)"
# NOTE: This regex matches that used in the release build.
- - "$LAUNCHER bin/ctest --output-on-failure -j$(nproc) -R '^(CMake\\.|CMakeLib\\.|CMakeServerLib\\.|RunCMake\\.ctest_memcheck)'"
+ - "$LAUNCHER bin/ctest --output-on-failure -j$(nproc) -R '^(CMake\\.|CMakeLib\\.|RunCMake\\.ctest_memcheck)'"
# Make a package.
- bin/cpack -G TGZ
- bin/cpack -G STGZ
diff --git a/Auxiliary/cmake-mode.el b/Auxiliary/cmake-mode.el
index 8224d9e..a11becb 100644
--- a/Auxiliary/cmake-mode.el
+++ b/Auxiliary/cmake-mode.el
@@ -41,8 +41,8 @@ set the path with these commands:
:group 'cmake)
;; Keywords
-(defconst cmake-keywords-block-open '("IF" "MACRO" "FOREACH" "ELSE" "ELSEIF" "WHILE" "FUNCTION"))
-(defconst cmake-keywords-block-close '("ENDIF" "ENDFOREACH" "ENDMACRO" "ELSE" "ELSEIF" "ENDWHILE" "ENDFUNCTION"))
+(defconst cmake-keywords-block-open '("BLOCK" "IF" "MACRO" "FOREACH" "ELSE" "ELSEIF" "WHILE" "FUNCTION"))
+(defconst cmake-keywords-block-close '("ENDBLOCK" "ENDIF" "ENDFOREACH" "ENDMACRO" "ELSE" "ELSEIF" "ENDWHILE" "ENDFUNCTION"))
(defconst cmake-keywords
(let ((kwds (append cmake-keywords-block-open cmake-keywords-block-close nil)))
(delete-dups kwds)))
@@ -288,6 +288,39 @@ This puts the mark at the end, and point at the beginning."
;------------------------------------------------------------------------------
+(defun cmake--syntax-propertize-until-bracket-close (syntax)
+ ;; This function assumes that a previous search has matched the
+ ;; beginning of a bracket_comment or bracket_argument and that the
+ ;; second capture group has matched the equal signs between the two
+ ;; opening brackets
+ (let* ((mb (match-beginning 2))
+ (me (match-end 2))
+ (cb (format "]%s]" (buffer-substring mb me))))
+ (save-match-data
+ (if (search-forward cb end 'move)
+ (progn
+ (setq me (match-end 0))
+ (put-text-property
+ (1- me)
+ me
+ 'syntax-table
+ (string-to-syntax syntax)))
+ (setq me end)))
+ (put-text-property
+ (match-beginning 1)
+ me
+ 'syntax-multiline
+ t)))
+
+(defconst cmake--syntax-propertize-function
+ (syntax-propertize-rules
+ ("\\(#\\)\\[\\(=*\\)\\["
+ (1
+ (prog1 "!" (cmake--syntax-propertize-until-bracket-close "!"))))
+ ("\\(\\[\\)\\(=*\\)\\["
+ (1
+ (prog1 "|" (cmake--syntax-propertize-until-bracket-close "|"))))))
+
;; Syntax table for this mode.
(defvar cmake-mode-syntax-table nil
"Syntax table for CMake mode.")
@@ -318,7 +351,10 @@ This puts the mark at the end, and point at the beginning."
; Setup indentation function.
(set (make-local-variable 'indent-line-function) 'cmake-indent)
; Setup comment syntax.
- (set (make-local-variable 'comment-start) "#"))
+ (set (make-local-variable 'comment-start) "#")
+ ;; Setup syntax propertization
+ (set (make-local-variable 'syntax-propertize-function) cmake--syntax-propertize-function)
+ (add-hook 'syntax-propertize-extend-region-functions #'syntax-propertize-multiline nil t))
;; Default cmake-mode key bindings
(define-key cmake-mode-map "\e\C-a" #'cmake-beginning-of-defun)
diff --git a/Auxiliary/vim/indent/cmake.vim b/Auxiliary/vim/indent/cmake.vim
index 672bdcc..0c662fa 100644
--- a/Auxiliary/vim/indent/cmake.vim
+++ b/Auxiliary/vim/indent/cmake.vim
@@ -59,8 +59,8 @@ fun! CMakeGetIndent(lnum)
let cmake_closing_parens_line = '^\s*\()\+\)\s*$'
- let cmake_indent_begin_regex = '^\s*\(IF\|MACRO\|FOREACH\|ELSE\|ELSEIF\|WHILE\|FUNCTION\)\s*('
- let cmake_indent_end_regex = '^\s*\(ENDIF\|ENDFOREACH\|ENDMACRO\|ELSE\|ELSEIF\|ENDWHILE\|ENDFUNCTION\)\s*('
+ let cmake_indent_begin_regex = '^\s*\(BLOCK\|IF\|MACRO\|FOREACH\|ELSE\|ELSEIF\|WHILE\|FUNCTION\)\s*('
+ let cmake_indent_end_regex = '^\s*\(ENDBLOCK\|ENDIF\|ENDFOREACH\|ENDMACRO\|ELSE\|ELSEIF\|ENDWHILE\|ENDFUNCTION\)\s*('
if this_line =~? cmake_closing_parens_line
if previous_line !~? cmake_indent_open_regex
diff --git a/Auxiliary/vim/syntax/cmake.vim b/Auxiliary/vim/syntax/cmake.vim
index e1a2885..9eb993a 100644
--- a/Auxiliary/vim/syntax/cmake.vim
+++ b/Auxiliary/vim/syntax/cmake.vim
@@ -436,6 +436,7 @@ syn keyword cmakeProperty contained
\ XCODE_SCHEME_ENVIRONMENT
\ XCODE_SCHEME_EXECUTABLE
\ XCODE_SCHEME_GUARD_MALLOC
+ \ XCODE_SCHEME_LAUNCH_MODE
\ XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
\ XCODE_SCHEME_MALLOC_GUARD_EDGES
\ XCODE_SCHEME_MALLOC_SCRIBBLE
@@ -444,6 +445,9 @@ syn keyword cmakeProperty contained
\ XCODE_SCHEME_THREAD_SANITIZER_STOP
\ XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
\ XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
+ \ XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+ \ XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
+ \ XCODE_SCHEME_LAUNCH_CONFIGURATION
\ XCODE_SCHEME_WORKING_DIRECTORY
\ XCODE_SCHEME_ZOMBIE_OBJECTS
\ XCTEST
@@ -1537,6 +1541,7 @@ syn keyword cmakeVariable contained
\ CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
\ CMAKE_XCODE_SCHEME_ENVIRONMENT
\ CMAKE_XCODE_SCHEME_GUARD_MALLOC
+ \ CMAKE_XCODE_SCHEME_LAUNCH_MODE
\ CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
\ CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
\ CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE
@@ -1545,6 +1550,9 @@ syn keyword cmakeVariable contained
\ CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP
\ CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
\ CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
+ \ CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+ \ CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
+ \ CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
\ CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
\ CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
\ CPACK_ABSOLUTE_DESTINATION_FILES
@@ -3830,6 +3838,7 @@ syn keyword cmakeCommand
\ add_subdirectory
\ add_test
\ aux_source_directory
+ \ block
\ break
\ build_command
\ cmake_host_system_information
@@ -3857,6 +3866,7 @@ syn keyword cmakeCommand
\ define_property
\ enable_language
\ enable_testing
+ \ endblock
\ endfunction
\ endmacro
\ execute_process
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9de5338..9d77dfc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
-cmake_minimum_required(VERSION 3.13...3.22 FATAL_ERROR)
+cmake_minimum_required(VERSION 3.13...3.23 FATAL_ERROR)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_C ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideC.cmake)
set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX ${CMAKE_CURRENT_SOURCE_DIR}/Source/Modules/OverrideCXX.cmake)
@@ -648,7 +648,7 @@ macro (CMAKE_BUILD_UTILITIES)
#---------------------------------------------------------------------
# Build jsoncpp library.
if(CMAKE_USE_SYSTEM_JSONCPP)
- find_package(JsonCpp 1.4.1)
+ find_package(JsonCpp 1.6.0)
if(NOT JsonCpp_FOUND)
message(FATAL_ERROR
"CMAKE_USE_SYSTEM_JSONCPP is ON but a JsonCpp is not found!")
@@ -883,9 +883,6 @@ add_subdirectory(Tests)
if(NOT CMake_TEST_EXTERNAL_CMAKE)
if(BUILD_TESTING)
CMAKE_SET_TARGET_FOLDER(CMakeLibTests "Tests")
- IF(TARGET CMakeServerLibTests)
- CMAKE_SET_TARGET_FOLDER(CMakeServerLibTests "Tests")
- ENDIF()
endif()
if(TARGET documentation)
CMAKE_SET_TARGET_FOLDER(documentation "Documentation")
diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in
index 49026a3..85af8ed 100644
--- a/CTestCustom.cmake.in
+++ b/CTestCustom.cmake.in
@@ -74,6 +74,7 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*rand.*may return deterministic values"
"cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*rand.*isn.*t random" # we do not do crypto
"cm(StringCommand|CTestTestHandler)\\.cxx.*warning.*srand.*seed choices are.*poor" # we do not do crypto
+ "cmFindPackageCommand.cxx.*: warning #177-D: parameter .* was declared but never referenced"
"IPA warning: function.*multiply defined in"
"LICENSE WARNING" # PGI license expiry. Not useful in nightly testing.
@@ -83,6 +84,11 @@ list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
"compilation completed with warnings" # PGI
"[0-9]+ Warning\\(s\\) detected" # SunPro
+ # Ignore false positive on `cm::optional` usage from GCC
+ "cmGlobalNinjaGenerator.cxx:[0-9]*:[0-9]*: warning: '.*cm::optional<CxxModuleMapFormat>::_mem\\)\\)' may be used uninitialized \\[-Wmaybe-uninitialized\\]"
+ "cmGlobalNinjaGenerator.cxx:[0-9]*:[0-9]*: note: '.*cm::optional<CxxModuleMapFormat>::_mem\\)\\)' was declared here"
+ "cmGlobalNinjaGenerator.cxx:[0-9]*:[0-9]*: warning: '\\*\\(\\(void\\*\\)& modmap_fmt \\+4\\)' may be used uninitialized in this function \\[-Wmaybe-uninitialized\\]"
+
# clang-analyzer exceptions
"cmListFileLexer.c:[0-9]+:[0-9]+: warning: Array subscript is undefined"
"jsoncpp/src/.*:[0-9]+:[0-9]+: warning: Value stored to .* is never read"
diff --git a/CompileFlags.cmake b/CompileFlags.cmake
index e6fb20b..47c8352 100644
--- a/CompileFlags.cmake
+++ b/CompileFlags.cmake
@@ -23,7 +23,7 @@ else()
endif()
if(MSVC)
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stack:10000000")
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${CMAKE_CXX_LINKER_WRAPPER_FLAG}-stack:10000000")
endif()
# MSVC 14.28 enables C5105, but the Windows SDK 10.0.18362.0 triggers it.
@@ -136,3 +136,12 @@ OFF to disable /MP completely." )
endif()
endif()
endif()
+
+# Get rid of excess -Wunused-but-set-variable on release builds with LCC >= 1.26
+foreach(l C CXX)
+ if(CMAKE_${l}_COMPILER_ID STREQUAL "LCC" AND NOT CMAKE_${l}_COMPILER_VERSION VERSION_LESS 1.26)
+ foreach(c MINSIZEREL RELEASE RELWITHDEBINFO)
+ string(APPEND "CMAKE_${l}_FLAGS_${c}" " -Wno-unused-but-set-variable")
+ endforeach()
+ endif()
+endforeach()
diff --git a/Copyright.txt b/Copyright.txt
index 2cf1769..bd45dd1 100644
--- a/Copyright.txt
+++ b/Copyright.txt
@@ -53,6 +53,7 @@ The following individuals and institutions are among the Contributors:
* Clement Creusot <creusot@cs.york.ac.uk>
* Daniel Blezek <blezek@gmail.com>
* Daniel Pfeifer <daniel@pfeifer-mail.de>
+* Dawid Wróbel <me@dawidwrobel.com>
* Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
* Eran Ifrah <eran.ifrah@gmail.com>
* Esben Mose Hansen, Ange Optimization ApS
diff --git a/Help/command/FIND_XXX.txt b/Help/command/FIND_XXX.txt
index cd3c78b..59a4e71 100644
--- a/Help/command/FIND_XXX.txt
+++ b/Help/command/FIND_XXX.txt
@@ -15,6 +15,7 @@ The general signature is:
[PATHS [path | ENV var]... ]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[PATH_SUFFIXES suffix1 [suffix2 ...]]
+ [VALIDATOR function]
[DOC "cache documentation string"]
[NO_CACHE]
[REQUIRED]
@@ -66,6 +67,26 @@ Options include:
Specify additional subdirectories to check below each directory
location otherwise considered.
+``VALIDATOR``
+ .. versionadded:: 3.25
+
+ Specify a :command:`function` (a :command:`macro` is not an acceptable
+ choice) which will be called for each found item. The search ends when
+ the validation function returns a successful status.
+
+ The validation function expects two arguments: output variable name and item
+ value. By default, the output variable name already holds a ``TRUE`` value.
+
+ .. parsed-literal::
+
+ function (MY_CHECK output_status item)
+ if (NOT item MATCHES ...)
+ set(${output_status} FALSE PARENT_SCOPE)
+ endif()
+ endfunction()
+
+ |FIND_XXX| (result NAMES ... VALIDATOR my_check)
+
``DOC``
Specify the documentation string for the ``<VAR>`` cache entry.
diff --git a/Help/command/block.rst b/Help/command/block.rst
new file mode 100644
index 0000000..9d37deb
--- /dev/null
+++ b/Help/command/block.rst
@@ -0,0 +1,75 @@
+block
+-----
+
+.. versionadded:: 3.25
+
+Evaluate a group of commands with a dedicated variable and/or policy scope.
+
+.. code-block:: cmake
+
+ block([SCOPE_FOR (POLICIES|VARIABLES)] [PROPAGATE <var-name>...])
+ <commands>
+ endblock()
+
+All commands between ``block()`` and the matching :command:`endblock` are
+recorded without being invoked. Once the :command:`endblock` is evaluated, the
+recorded list of commands is invoked inside the requested scopes, and, finally,
+the scopes created by ``block()`` command are removed.
+
+``SCOPE_FOR``
+ Specify which scopes must be created.
+
+ ``POLICIES``
+ Create a new policy scope. This is equivalent to
+ :command:`cmake_policy(PUSH)`.
+
+ ``VARIABLES``
+ Create a new variable scope.
+
+ If ``SCOPE_FOR`` is not specified, this is equivalent to:
+
+ .. code-block:: cmake
+
+ block(SCOPE_FOR VARIABLES POLICIES)
+
+``PROPAGATE``
+ When a variable scope is created by :command:`block` command, this option
+ set or unset the specified variables in the parent scope. This is equivalent
+ to :command:`set(PARENT_SCOPE)` or :command:`unset(PARENT_SCOPE)` commands.
+
+ .. code-block:: cmake
+
+ set(VAR1 "INIT1")
+ set(VAR2 "INIT2")
+
+ block(PROPAGATE VAR1 VAR2)
+ set(VAR1 "VALUE1")
+ unset(VAR2)
+ endblock()
+
+ # here, VAR1 holds value VALUE1 and VAR2 is unset
+
+ This option is only allowed when a variable scope is created. An error will
+ be raised in the other cases.
+
+When the ``block`` is local to a :command:`foreach` or :command:`while`
+command, the commands :command:`break` and :command:`continue` can be used
+inside this block.
+
+.. code-block:: cmake
+
+ while(TRUE)
+ block()
+ ...
+ # the break() command will terminate the while() command
+ break()
+ endblock()
+ endwhile()
+
+
+See Also
+^^^^^^^^
+
+ * :command:`endblock`
+ * :command:`return`
+ * :command:`cmake_policy`
diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst
index cb8d60b..8801a9f 100644
--- a/Help/command/cmake_language.rst
+++ b/Help/command/cmake_language.rst
@@ -14,6 +14,7 @@ Synopsis
cmake_language(`EVAL`_ CODE <code>...)
cmake_language(`DEFER`_ <options>... CALL <command> [<arg>...])
cmake_language(`SET_DEPENDENCY_PROVIDER`_ <command> SUPPORTED_METHODS <methods>...)
+ cmake_language(`GET_MESSAGE_LOG_LEVEL`_ <out-var>)
Introduction
^^^^^^^^^^^^
@@ -50,6 +51,7 @@ is equivalent to
To ensure consistency of the code, the following commands are not allowed:
* ``if`` / ``elseif`` / ``else`` / ``endif``
+ * ``block`` / ``endblock``
* ``while`` / ``endwhile``
* ``foreach`` / ``endforeach``
* ``function`` / ``endfunction``
@@ -491,3 +493,29 @@ calling the provider command recursively for the same dependency.
SET_DEPENDENCY_PROVIDER mycomp_provide_dependency
SUPPORTED_METHODS FIND_PACKAGE
)
+
+Getting current message log level
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.25
+
+.. _GET_MESSAGE_LOG_LEVEL:
+.. _query_message_log_level:
+
+.. code-block:: cmake
+
+ cmake_language(GET_MESSAGE_LOG_LEVEL <output_variable>)
+
+Writes the current :command:`message` logging level
+into the given ``<output_variable>``.
+
+See :command:`message` for the possible logging levels.
+
+The current message logging level can be set either using the
+:option:`--log-level <cmake --log-level>`
+command line option of the :manual:`cmake(1)` program or using
+the :variable:`CMAKE_MESSAGE_LOG_LEVEL` variable.
+
+If both the command line option and the variable are set, the command line
+option takes precedence. If neither are set, the default logging level
+is returned.
diff --git a/Help/command/cmake_policy.rst b/Help/command/cmake_policy.rst
index 94060d9..54fc548 100644
--- a/Help/command/cmake_policy.rst
+++ b/Help/command/cmake_policy.rst
@@ -103,6 +103,47 @@ Calls to the :command:`cmake_minimum_required(VERSION)`,
``cmake_policy(VERSION)``, or ``cmake_policy(SET)`` commands
influence only the current top of the policy stack.
+.. versionadded:: 3.25
+ The :command:`block` and :command:`endblock` commands offer a more flexible
+ and more secure way to manage the policy stack. The pop action is done
+ automatically when the :command:`endblock` command is executed, so it avoid
+ to call the :command:`cmake_policy(POP)` command before each
+ :command:`return` command.
+
+ .. code-block:: cmake
+
+ # stack management with cmake_policy()
+ function(my_func)
+ cmake_policy(PUSH)
+ cmake_policy(SET ...)
+ if (<cond1>)
+ ...
+ cmake_policy(POP)
+ return()
+ elseif(<cond2>)
+ ...
+ cmake_policy(POP)
+ return()
+ endif()
+ ...
+ cmake_policy(POP)
+ endfunction()
+
+ # stack management with block()/endblock()
+ function(my_func)
+ block(SCOPE_FOR POLICIES)
+ cmake_policy(SET ...)
+ if (<cond1>)
+ ...
+ return()
+ elseif(<cond2>)
+ ...
+ return()
+ endif()
+ ...
+ endblock()
+ endfunction()
+
Commands created by the :command:`function` and :command:`macro`
commands record policy settings when they are created and
use the pre-record policies when they are invoked. If the function or
diff --git a/Help/command/ctest_run_script.rst b/Help/command/ctest_run_script.rst
index 5ec543e..a2b348f 100644
--- a/Help/command/ctest_run_script.rst
+++ b/Help/command/ctest_run_script.rst
@@ -1,15 +1,15 @@
ctest_run_script
----------------
-runs a ctest -S script
+runs a :option:`ctest -S` script
::
ctest_run_script([NEW_PROCESS] script_file_name script_file_name1
script_file_name2 ... [RETURN_VALUE var])
-Runs a script or scripts much like if it was run from ctest -S. If no
-argument is provided then the current script is run using the current
+Runs a script or scripts much like if it was run from :option:`ctest -S`.
+If no argument is provided then the current script is run using the current
settings of the variables. If ``NEW_PROCESS`` is specified then each
script will be run in a separate process.If ``RETURN_VALUE`` is specified
the return value of the last script run will be put into ``var``.
diff --git a/Help/command/ctest_start.rst b/Help/command/ctest_start.rst
index c0f3c6d..921279a 100644
--- a/Help/command/ctest_start.rst
+++ b/Help/command/ctest_start.rst
@@ -45,7 +45,7 @@ The parameters are as follows:
ctest_start(Experimental GROUP GroupExperimental)
- Later, in another ``ctest -S`` script:
+ Later, in another :option:`ctest -S` script:
.. code-block:: cmake
diff --git a/Help/command/ctest_test.rst b/Help/command/ctest_test.rst
index 65f82d7..4f9f891 100644
--- a/Help/command/ctest_test.rst
+++ b/Help/command/ctest_test.rst
@@ -109,8 +109,9 @@ The options are:
While running tests in parallel, try not to start tests when they
may cause the CPU load to pass above a given threshold. If not
specified the :variable:`CTEST_TEST_LOAD` variable will be checked,
- and then the ``--test-load`` command-line argument to :manual:`ctest(1)`.
- See also the ``TestLoad`` setting in the :ref:`CTest Test Step`.
+ and then the :option:`--test-load <ctest --test-load>` command-line
+ argument to :manual:`ctest(1)`. See also the ``TestLoad`` setting
+ in the :ref:`CTest Test Step`.
``REPEAT <mode>:<n>``
.. versionadded:: 3.17
@@ -176,8 +177,9 @@ See also the :variable:`CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE`,
:variable:`CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE` and
:variable:`CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION` variables, along with their
corresponding :manual:`ctest(1)` command line options
-``--test-output-size-passed``, ``--test-output-size-failed``, and
-``--test-output-truncation``.
+:option:`--test-output-size-passed <ctest --test-output-size-passed>`,
+:option:`--test-output-size-failed <ctest --test-output-size-failed>`, and
+:option:`--test-output-truncation <ctest --test-output-truncation>`.
.. _`Additional Test Measurements`:
diff --git a/Help/command/enable_language.rst b/Help/command/enable_language.rst
index d2acbc8..d9103b8 100644
--- a/Help/command/enable_language.rst
+++ b/Help/command/enable_language.rst
@@ -1,13 +1,14 @@
enable_language
---------------
-Enable a language (CXX/C/OBJC/OBJCXX/Fortran/etc)
+
+Enable languages (CXX/C/OBJC/OBJCXX/Fortran/etc)
.. code-block:: cmake
- enable_language(<lang> [OPTIONAL] )
+ enable_language(<lang>... [OPTIONAL])
-Enables support for the named language in CMake. This is
-the same as the :command:`project` command but does not create any of the extra
+Enables support for the named languages in CMake. This is the same as
+the :command:`project` command but does not create any of the extra
variables that are created by the project command. Example languages
are ``CXX``, ``C``, ``CUDA``, ``OBJC``, ``OBJCXX``, ``Fortran``,
``HIP``, ``ISPC``, and ``ASM``.
diff --git a/Help/command/endblock.rst b/Help/command/endblock.rst
new file mode 100644
index 0000000..3b21c12
--- /dev/null
+++ b/Help/command/endblock.rst
@@ -0,0 +1,11 @@
+endblock
+--------
+
+.. versionadded:: 3.25
+
+Ends a list of commands in a :command:`block` and removes the scopes
+created by the :command:`block` command.
+
+.. code-block:: cmake
+
+ endblock()
diff --git a/Help/command/export.rst b/Help/command/export.rst
index dc69645..0f79f63 100644
--- a/Help/command/export.rst
+++ b/Help/command/export.rst
@@ -25,7 +25,8 @@ Exporting Targets
.. code-block:: cmake
export(TARGETS <target>... [NAMESPACE <namespace>]
- [APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES])
+ [APPEND] FILE <filename> [EXPORT_LINK_INTERFACE_LIBRARIES]
+ [CXX_MODULES_DIRECTORY <directory>])
Creates a file ``<filename>`` that may be included by outside projects to
import targets named by ``<target>...`` from the current project's build tree.
@@ -52,6 +53,16 @@ The options are:
in the export, even when policy :policy:`CMP0022` is NEW. This is useful
to support consumers using CMake versions older than 2.8.12.
+``CXX_MODULES_DIRECTORY <directory>``
+
+ .. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+ Export C++ module properties to files under the given directory. Each file
+ will be named according to the target's export name (without any namespace).
+ These files will automatically be included from the export file.
+
This signature requires all targets to be listed explicitly. If a library
target is included in the export, but a target to which it links is not
included, the behavior is unspecified. See the `export(EXPORT)`_ signature
@@ -95,7 +106,8 @@ Exporting Targets matching install(EXPORT)
.. code-block:: cmake
- export(EXPORT <export-name> [NAMESPACE <namespace>] [FILE <filename>])
+ export(EXPORT <export-name> [NAMESPACE <namespace>] [FILE <filename>]
+ [CXX_MODULES_DIRECTORY <directory>])
Creates a file ``<filename>`` that may be included by outside projects to
import targets from the current project's build tree. This is the same
diff --git a/Help/command/file.rst b/Help/command/file.rst
index 3374d2d..fbe2a81 100644
--- a/Help/command/file.rst
+++ b/Help/command/file.rst
@@ -1121,8 +1121,11 @@ Additional options to ``DOWNLOAD`` are:
Verify that the downloaded content hash matches the expected value, where
``ALGO`` is one of the algorithms supported by ``file(<HASH>)``.
- If it does not match, the operation fails with an error. It is an error to
- specify this if ``DOWNLOAD`` is not given a ``<file>``.
+ If the file already exists and matches the hash, the download is skipped.
+ If the file already exists and does not match the hash, the file is
+ downloaded again. If after download the file does not match the hash, the
+ operation fails with an error. It is an error to specify this option if
+ ``DOWNLOAD`` is not given a ``<file>``.
``EXPECTED_MD5 <value>``
Historical short-hand for ``EXPECTED_HASH MD5=<value>``. It is an error to
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index c96d84e..7f076f9 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -291,6 +291,7 @@ Each entry is meant for installation trees following Windows (``W``), UNIX
<prefix>/(cmake|CMake)/ (W)
<prefix>/<name>*/ (W)
<prefix>/<name>*/(cmake|CMake)/ (W)
+ <prefix>/<name>*/(cmake|CMake)/<name>*/ (W)
<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/ (U)
<prefix>/(lib/<arch>|lib*|share)/<name>*/ (U)
<prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (U)
@@ -368,7 +369,7 @@ enabled.
See policy :policy:`CMP0074`.
2. Search paths specified in cmake-specific cache variables. These
- are intended to be used on the command line with a ``-DVAR=value``.
+ are intended to be used on the command line with a :option:`-DVAR=VALUE <cmake -D>`.
The values are interpreted as :ref:`semicolon-separated lists <CMake Language Lists>`.
This can be skipped if ``NO_CMAKE_PATH`` is passed or by setting the
:variable:`CMAKE_FIND_USE_CMAKE_PATH` to ``FALSE``:
diff --git a/Help/command/foreach.rst b/Help/command/foreach.rst
index d9f54ca..ddf8dfa 100644
--- a/Help/command/foreach.rst
+++ b/Help/command/foreach.rst
@@ -130,3 +130,11 @@ yields
-- en=two, ba=dua
-- en=three, ba=tiga
-- en=four, ba=
+
+See Also
+^^^^^^^^
+
+* :command:`break`
+* :command:`continue`
+* :command:`endforeach`
+* :command:`while`
diff --git a/Help/command/function.rst b/Help/command/function.rst
index 3d25aa4..fc55c03 100644
--- a/Help/command/function.rst
+++ b/Help/command/function.rst
@@ -73,3 +73,9 @@ argument. Referencing to ``ARGV#`` arguments beyond ``ARGC`` have
undefined behavior. Checking that ``ARGC`` is greater than ``#`` is
the only way to ensure that ``ARGV#`` was passed to the function as an
extra argument.
+
+See Also
+^^^^^^^^
+
+* :command:`endfunction`
+* :command:`return`
diff --git a/Help/command/get_test_property.rst b/Help/command/get_test_property.rst
index e02b9bc..6bcc1ef 100644
--- a/Help/command/get_test_property.rst
+++ b/Help/command/get_test_property.rst
@@ -16,6 +16,7 @@ relevant parent scope as described for the :command:`define_property`
command and if still unable to find the property, ``VAR`` will be set to
an empty string.
-For a list of standard properties you can type ``cmake --help-property-list``.
+For a list of standard properties you can type
+:option:`cmake --help-property-list`.
See also the more general :command:`get_property` command.
diff --git a/Help/command/if.rst b/Help/command/if.rst
index 301cdce..b72769f 100644
--- a/Help/command/if.rst
+++ b/Help/command/if.rst
@@ -424,3 +424,10 @@ There is no automatic evaluation for environment or cache
:ref:`Variable References`. Their values must be referenced as
``$ENV{<name>}`` or ``$CACHE{<name>}`` wherever the above-documented
condition syntax accepts ``<variable|string>``.
+
+See also
+^^^^^^^^
+
+ * :command:`else`
+ * :command:`elseif`
+ * :command:`endif`
diff --git a/Help/command/install.rst b/Help/command/install.rst
index 973aa31..45da99b 100644
--- a/Help/command/install.rst
+++ b/Help/command/install.rst
@@ -132,7 +132,7 @@ Installing Targets
install(TARGETS targets... [EXPORT <export-name>]
[RUNTIME_DEPENDENCIES args...|RUNTIME_DEPENDENCY_SET <set-name>]
[[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
- PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET <set-name>]
+ PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE|FILE_SET <set-name>|CXX_MODULES_BMI]
[DESTINATION <dir>]
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
@@ -215,11 +215,21 @@ that may be installed:
``/blah/include/myproj/here.h`` with a base directory ``/blah/include``
would be installed to ``myproj/here.h`` below the destination.
+``CXX_MODULES_BMI``
+
+ .. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+ Any module files from C++ modules from ``PUBLIC`` sources in a file set of
+ type ``CXX_MODULES`` will be installed to the given ``DESTINATION``. All
+ modules are placed directly in the destination as no directory structure is
+ derived from the names of the modules. An empty ``DESTINATION`` may be used
+ to suppress installing these files (for use in generic code).
+
For each of these arguments given, the arguments following them only apply
to the target or file type specified in the argument. If none is given, the
-installation properties apply to all target types. If only one is given then
-only targets of that type will be installed (which can be used to install
-just a DLL or just an import library.)
+installation properties apply to all target types.
For regular executables, static libraries and shared libraries, the
``DESTINATION`` argument is not required. For these target types, when
@@ -233,6 +243,14 @@ Apple bundles and frameworks. A destination can be omitted for interface and
object libraries, but they are handled differently (see the discussion of this
topic toward the end of this section).
+For shared libraries on DLL platforms, if neither ``RUNTIME`` nor ``ARCHIVE``
+destinations are specified, both the ``RUNTIME`` and ``ARCHIVE`` components are
+installed to their default destinations. If either a ``RUNTIME`` or ``ARCHIVE``
+destination is specified, the component is installed to that destination, and
+the other component is not installed. If both ``RUNTIME`` and ``ARCHIVE``
+destinations are specified, then both components are installed to their
+respective destinations.
+
The following table shows the target types with their associated variables and
built-in defaults that apply when no destination is given:
@@ -778,9 +796,10 @@ Installing Exports
.. code-block:: cmake
install(EXPORT <export-name> DESTINATION <dir>
- [NAMESPACE <namespace>] [[FILE <name>.cmake]|
+ [NAMESPACE <namespace>] [FILE <name>.cmake]
[PERMISSIONS permissions...]
- [CONFIGURATIONS [Debug|Release|...]]
+ [CONFIGURATIONS [Debug|Release|...]
+ [CXX_MODULES_DIRECTORY <directory>]
[EXPORT_LINK_INTERFACE_LIBRARIES]
[COMPONENT <component>]
[EXCLUDE_FROM_ALL])
@@ -836,6 +855,18 @@ library is always installed if the headers and CMake export file are present.
to an ndk build system complete with transitive dependencies, include flags
and defines required to use the libraries.
+``CXX_MODULES_DIRECTORY``
+
+ .. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+ Specify a subdirectory to store C++ module information for targets in the
+ export set. This directory will be populated with files which add the
+ necessary target property information to the relevant targets. Note that
+ without this information, none of the C++ modules which are part of the
+ targets in the export set will support being imported in consuming targets.
+
The ``EXPORT`` form is useful to help outside projects use targets built
and installed by the current project. For example, the code
@@ -932,12 +963,12 @@ Generated Installation Script
.. note::
Use of this feature is not recommended. Please consider using the
- ``--install`` argument of :manual:`cmake(1)` instead.
+ :option:`cmake --install` instead.
The ``install()`` command generates a file, ``cmake_install.cmake``, inside
the build directory, which is used internally by the generated install target
-and by CPack. You can also invoke this script manually with ``cmake -P``. This
-script accepts several variables:
+and by CPack. You can also invoke this script manually with
+:option:`cmake -P <cmake_P -P>`. This script accepts several variables:
``COMPONENT``
Set this variable to install only a single CPack component as opposed to all
diff --git a/Help/command/message.rst b/Help/command/message.rst
index ca4f5c1..77d21c8 100644
--- a/Help/command/message.rst
+++ b/Help/command/message.rst
@@ -83,8 +83,9 @@ are sent to stderr and are not prefixed with hyphens. The
:manual:`CMake GUI <cmake-gui(1)>` displays all messages in its log area.
The :manual:`curses interface <ccmake(1)>` shows ``STATUS`` to ``TRACE``
messages one at a time on a status line and other messages in an
-interactive pop-up box. The ``--log-level`` command-line option to each of
-these tools can be used to control which messages will be shown.
+interactive pop-up box. The :option:`--log-level <cmake --log-level>`
+command-line option to each of these tools can be used to control which
+messages will be shown.
.. versionadded:: 3.17
To make a log level persist between CMake runs, the
@@ -104,7 +105,7 @@ these tools can be used to control which messages will be shown.
list variable to a dot-separated string. The message context will always
appear before any indenting content but after any automatically added leading
hyphens. By default, message context is not shown, it has to be explicitly
- enabled by giving the :manual:`cmake <cmake(1)>` ``--log-context``
+ enabled by giving the :option:`cmake --log-context`
command-line option or by setting the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
variable to true. See the :variable:`CMAKE_MESSAGE_CONTEXT` documentation for
usage examples.
diff --git a/Help/command/return.rst b/Help/command/return.rst
index ec009d8..029fd05 100644
--- a/Help/command/return.rst
+++ b/Help/command/return.rst
@@ -5,7 +5,7 @@ Return from a file, directory or function.
.. code-block:: cmake
- return()
+ return([PROPAGATE <var-name>...])
Returns from a file, directory or function. When this command is
encountered in an included file (via :command:`include` or
@@ -16,5 +16,39 @@ deferred calls scheduled by :command:`cmake_language(DEFER)` are invoked and
control is returned to the parent directory if there is one. If return is
called in a function, control is returned to the caller of the function.
+``PROPAGATE``
+ .. versionadded:: 3.25
+
+ This option set or unset the specified variables in the parent directory or
+ function caller scope. This is equivalent to :command:`set(PARENT_SCOPE)` or
+ :command:`unset(PARENT_SCOPE)` commands.
+
+ The option ``PROPAGATE`` can be very useful in conjunction with the
+ :command:`block` command because the :command:`return` will cross over
+ various scopes created by the :command:`block` commands.
+
+ .. code-block:: cmake
+
+ function(MULTI_SCOPES RESULT_VARIABLE)
+ block(SCOPE_FOR VARIABLES)
+ # here set(PARENT_SCOPE) is not usable because it will not set the
+ # variable in the caller scope but in the parent scope of the block()
+ set(${RESULT_VARIABLE} "new-value")
+ return(PROPAGATE ${RESULT_VARIABLE})
+ endblock()
+ endfunction()
+
+ set(MY_VAR "initial-value")
+ multi_scopes(MY_VAR)
+ # here MY_VAR will holds "new-value"
+
+Policy :policy:`CMP0140` controls the behavior regarding the arguments of the
+command.
+
Note that a :command:`macro <macro>`, unlike a :command:`function <function>`,
is expanded in place and therefore cannot handle ``return()``.
+
+See Also
+^^^^^^^^
+
+ * :command:`block`
diff --git a/Help/command/set.rst b/Help/command/set.rst
index af862e4..5e05d9b 100644
--- a/Help/command/set.rst
+++ b/Help/command/set.rst
@@ -22,12 +22,17 @@ Set Normal Variable
Sets the given ``<variable>`` in the current function or directory scope.
If the ``PARENT_SCOPE`` option is given the variable will be set in
-the scope above the current scope. Each new directory or function
-creates a new scope. This command will set the value of a variable
-into the parent directory or calling function (whichever is applicable
-to the case at hand). The previous state of the variable's value stays the
-same in the current scope (e.g., if it was undefined before, it is still
-undefined and if it had a value, it is still that value).
+the scope above the current scope. Each new directory or :command:`function`
+command creates a new scope. A scope can also be created with the
+:command:`block` command. This command will set the value of a variable into
+the parent directory, calling function or encompassing scope (whichever is
+applicable to the case at hand). The previous state of the variable's value
+stays the same in the current scope (e.g., if it was undefined before, it is
+still undefined and if it had a value, it is still that value).
+
+The :command:`block(PROPAGATE)` and :command:`return(PROPAGATE)` commands can
+be used as an alternate method to the :command:`set(PARENT_SCOPE)` and
+:command:`unset(PARENT_SCOPE)` commands to update the parent scope.
Set Cache Entry
^^^^^^^^^^^^^^^
diff --git a/Help/command/target_sources.rst b/Help/command/target_sources.rst
index 72119f6..146b850 100644
--- a/Help/command/target_sources.rst
+++ b/Help/command/target_sources.rst
@@ -75,9 +75,33 @@ File Sets
Adds a file set to a target, or adds files to an existing file set. Targets
have zero or more named file sets. Each file set has a name, a type, a scope of
``INTERFACE``, ``PUBLIC``, or ``PRIVATE``, one or more base directories, and
-files within those directories. The only acceptable type is ``HEADERS``. The
-optional default file sets are named after their type. The target may not be a
-custom target or :prop_tgt:`FRAMEWORK` target.
+files within those directories. The acceptable types include:
+
+``HEADERS``
+
+ Sources intended to be used via a language's ``#include`` mechanism.
+
+``CXX_MODULES``
+
+ .. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+ Sources which contain C++ interface module or partition units (i.e., those
+ using the ``export`` keyword). This file set type may not have an
+ ``INTERFACE`` scope except on ``IMPORTED`` targets.
+
+``CXX_MODULE_HEADER_UNITS``
+
+ .. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+ C++ header sources which may be imported by other C++ source code. This file
+ set type may not have an ``INTERFACE`` scope except on ``IMPORTED`` targets.
+
+The optional default file sets are named after their type. The target may not
+be a custom target or :prop_tgt:`FRAMEWORK` target.
Files in a ``PRIVATE`` or ``PUBLIC`` file set are marked as source files for
the purposes of IDE integration. Additionally, files in ``HEADERS`` file sets
@@ -93,16 +117,17 @@ Each ``target_sources(FILE_SET)`` entry starts with ``INTERFACE``, ``PUBLIC``, o
The name of the file set to create or add to. It must contain only letters,
numbers and underscores. Names starting with a capital letter are reserved
- for built-in file sets predefined by CMake. The only predefined set name is
- ``HEADERS``. All other set names must not start with a capital letter or
+ for built-in file sets predefined by CMake. The only predefined set names
+ are those matching the acceptable types. All other set names must not start
+ with a capital letter or
underscore.
``TYPE <type>``
- Every file set is associated with a particular type of file. ``HEADERS``
- is currently the only defined type and it is an error to specify anything
- else. As a special case, if the name of the file set is ``HEADERS``, the
- type does not need to be specified and the ``TYPE <type>`` arguments can be
+ Every file set is associated with a particular type of file. Only types
+ specified above may be used and it is an error to specify anything else. As
+ a special case, if the name of the file set is one of the types, the type
+ does not need to be specified and the ``TYPE <type>`` arguments can be
omitted. For all other file set names, ``TYPE`` is required.
``BASE_DIRS <dirs>...``
@@ -134,6 +159,8 @@ Each ``target_sources(FILE_SET)`` entry starts with ``INTERFACE``, ``PUBLIC``, o
The following target properties are set by ``target_sources(FILE_SET)``,
but they should not generally be manipulated directly:
+For file sets of type ``HEADERS``:
+
* :prop_tgt:`HEADER_SETS`
* :prop_tgt:`INTERFACE_HEADER_SETS`
* :prop_tgt:`HEADER_SET`
@@ -141,17 +168,37 @@ but they should not generally be manipulated directly:
* :prop_tgt:`HEADER_DIRS`
* :prop_tgt:`HEADER_DIRS_<NAME>`
+For file sets of type ``CXX_MODULES``:
+
+* :prop_tgt:`CXX_MODULE_SETS`
+* :prop_tgt:`INTERFACE_CXX_MODULE_SETS`
+* :prop_tgt:`CXX_MODULE_SET`
+* :prop_tgt:`CXX_MODULE_SET_<NAME>`
+* :prop_tgt:`CXX_MODULE_DIRS`
+* :prop_tgt:`CXX_MODULE_DIRS_<NAME>`
+
+For file sets of type ``CXX_MODULE_HEADER_UNITS``:
+
+* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS`
+* :prop_tgt:`INTERFACE_CXX_MODULE_HEADER_UNIT_SETS`
+* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET`
+* :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET_<NAME>`
+* :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS`
+* :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS_<NAME>`
+
Target properties related to include directories are also modified by
``target_sources(FILE_SET)`` as follows:
:prop_tgt:`INCLUDE_DIRECTORIES`
- If the ``TYPE`` is ``HEADERS``, and the scope of the file set is ``PRIVATE``
- or ``PUBLIC``, all of the ``BASE_DIRS`` of the file set are wrapped in
- :genex:`$<BUILD_INTERFACE>` and appended to this property.
+ If the ``TYPE`` is ``HEADERS`` or ``CXX_MODULE_HEADER_UNITS``, and the scope
+ of the file set is ``PRIVATE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of
+ the file set are wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this
+ property.
:prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`
- If the ``TYPE`` is ``HEADERS``, and the scope of the file set is
- ``INTERFACE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of the file set are
- wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this property.
+ If the ``TYPE`` is ``HEADERS`` or ``CXX_MODULE_HEADER_UNITS``, and the scope
+ of the file set is ``INTERFACE`` or ``PUBLIC``, all of the ``BASE_DIRS`` of
+ the file set are wrapped in :genex:`$<BUILD_INTERFACE>` and appended to this
+ property.
diff --git a/Help/command/try_compile.rst b/Help/command/try_compile.rst
index 806a98d..73dd9d3 100644
--- a/Help/command/try_compile.rst
+++ b/Help/command/try_compile.rst
@@ -41,7 +41,7 @@ Try Compiling Source Files
.. code-block:: cmake
- try_compile(<resultVar> <bindir> <srcfile|SOURCES srcfile...>
+ try_compile(<resultVar> SOURCES <srcfile...>
[CMAKE_FLAGS <flags>...]
[COMPILE_DEFINITIONS <defs>...]
[LINK_OPTIONS <options>...]
@@ -53,6 +53,8 @@ Try Compiling Source Files
[<LANG>_EXTENSIONS <bool>]
)
+.. versionadded:: 3.25
+
Try building an executable or static library from one or more source files
(which one is determined by the :variable:`CMAKE_TRY_COMPILE_TARGET_TYPE`
variable). The success or failure of the ``try_compile``, i.e. ``TRUE`` or
@@ -76,11 +78,44 @@ contain something like the following:
target_link_options(cmTryCompileExec PRIVATE <LINK_OPTIONS from caller>)
target_link_libraries(cmTryCompileExec ${LINK_LIBRARIES})
+CMake will automatically generate a unique directory for each ``try_compile``
+operation in an unspecified location within the project's binary directory.
+These directories will be cleaned automatically unless
+:option:`--debug-trycompile <cmake --debug-trycompile>` is passed to ``cmake``.
+Such directories from previous runs are also unconditionally cleaned at the
+beginning of any ``cmake`` execution.
+
+This command also supports an alternate signature
+which was present in older versions of CMake:
+
+.. code-block:: cmake
+
+ try_compile(<resultVar> <bindir> <srcfile|SOURCES srcfile...>
+ [CMAKE_FLAGS <flags>...]
+ [COMPILE_DEFINITIONS <defs>...]
+ [LINK_OPTIONS <options>...]
+ [LINK_LIBRARIES <libs>...]
+ [OUTPUT_VARIABLE <var>]
+ [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
+ [<LANG>_STANDARD <std>]
+ [<LANG>_STANDARD_REQUIRED <bool>]
+ [<LANG>_EXTENSIONS <bool>]
+ )
+
+In this version, ``try_compile`` will use ``<bindir>/CMakeFiles/CMakeTmp`` for
+its operation, and all such files will be cleaned automatically.
+For debugging, :option:`--debug-trycompile <cmake --debug-trycompile>` can be
+passed to ``cmake`` to avoid this clean. However, multiple sequential
+``try_compile`` operations, if given the same ``<bindir>``, will reuse this
+single output directory, such that you can only debug one such ``try_compile``
+call at a time. Use of the newer signature is recommended to simplify
+debugging of multiple ``try_compile`` operations.
+
The options are:
``CMAKE_FLAGS <flags>...``
- Specify flags of the form ``-DVAR:TYPE=VALUE`` to be passed to
- the ``cmake`` command-line used to drive the test build.
+ Specify flags of the form :option:`-DVAR:TYPE=VALUE <cmake -D>` to be passed
+ to the :manual:`cmake(1)` command-line used to drive the test build.
The above example shows how values for variables
``INCLUDE_DIRECTORIES``, ``LINK_DIRECTORIES``, and ``LINK_LIBRARIES``
are used.
@@ -136,17 +171,6 @@ The options are:
:prop_tgt:`OBJC_EXTENSIONS`, :prop_tgt:`OBJCXX_EXTENSIONS`,
or :prop_tgt:`CUDA_EXTENSIONS` target property of the generated project.
-In this version all files in ``<bindir>/CMakeFiles/CMakeTmp`` will be
-cleaned automatically. For debugging, ``--debug-trycompile`` can be
-passed to ``cmake`` to avoid this clean. However, multiple sequential
-``try_compile`` operations reuse this single output directory. If you use
-``--debug-trycompile``, you can only debug one ``try_compile`` call at a time.
-The recommended procedure is to protect all ``try_compile`` calls in your
-project by ``if(NOT DEFINED <resultVar>)`` logic, configure with cmake
-all the way through once, then delete the cache entry associated with
-the try_compile call of interest, and then re-run cmake again with
-``--debug-trycompile``.
-
Other Behavior Settings
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/Help/command/try_run.rst b/Help/command/try_run.rst
index fc41cdd..1dc2355 100644
--- a/Help/command/try_run.rst
+++ b/Help/command/try_run.rst
@@ -12,69 +12,91 @@ Try Compiling and Running Source Files
.. code-block:: cmake
- try_run(<runResultVar> <compileResultVar>
- <bindir> <srcfile> [CMAKE_FLAGS <flags>...]
+ try_run(<runResultVar> <compileResultVar> SOURCES <srcfile...>
+ [CMAKE_FLAGS <flags>...]
[COMPILE_DEFINITIONS <defs>...]
[LINK_OPTIONS <options>...]
[LINK_LIBRARIES <libs>...]
[COMPILE_OUTPUT_VARIABLE <var>]
+ [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
+ [<LANG>_STANDARD <std>]
+ [<LANG>_STANDARD_REQUIRED <bool>]
+ [<LANG>_EXTENSIONS <bool>]
[RUN_OUTPUT_VARIABLE <var>]
+ [RUN_OUTPUT_STDOUT_VARIABLE <var>]
+ [RUN_OUTPUT_STDERR_VARIABLE <var>]
[OUTPUT_VARIABLE <var>]
[WORKING_DIRECTORY <var>]
- [ARGS <args>...])
+ [ARGS <args>...]
+ )
+
+.. versionadded:: 3.25
Try compiling a ``<srcfile>``. Returns ``TRUE`` or ``FALSE`` for success
or failure in ``<compileResultVar>``. If the compile succeeded, runs the
executable and returns its exit code in ``<runResultVar>``. If the
executable was built, but failed to run, then ``<runResultVar>`` will be
set to ``FAILED_TO_RUN``. See the :command:`try_compile` command for
-information on how the test project is constructed to build the source file.
+documentation of options common to both commands, and for information on how
+the test project is constructed to build the source file.
+
+This command also supports an alternate signature
+which was present in older versions of CMake:
-The options are:
+.. code-block:: cmake
-``CMAKE_FLAGS <flags>...``
- Specify flags of the form ``-DVAR:TYPE=VALUE`` to be passed to
- the ``cmake`` command-line used to drive the test build.
- The example in :command:`try_compile` shows how values for variables
- ``INCLUDE_DIRECTORIES``, ``LINK_DIRECTORIES``, and ``LINK_LIBRARIES``
- are used.
+ try_run(<runResultVar> <compileResultVar>
+ <bindir> <srcfile|SOURCES srcfile...>
+ [CMAKE_FLAGS <flags>...]
+ [COMPILE_DEFINITIONS <defs>...]
+ [LINK_OPTIONS <options>...]
+ [LINK_LIBRARIES <libs>...]
+ [COMPILE_OUTPUT_VARIABLE <var>]
+ [COPY_FILE <fileName> [COPY_FILE_ERROR <var>]]
+ [<LANG>_STANDARD <std>]
+ [<LANG>_STANDARD_REQUIRED <bool>]
+ [<LANG>_EXTENSIONS <bool>]
+ [RUN_OUTPUT_VARIABLE <var>]
+ [RUN_OUTPUT_STDOUT_VARIABLE <var>]
+ [RUN_OUTPUT_STDERR_VARIABLE <var>]
+ [OUTPUT_VARIABLE <var>]
+ [WORKING_DIRECTORY <var>]
+ [ARGS <args>...]
+ )
-``COMPILE_DEFINITIONS <defs>...``
- Specify ``-Ddefinition`` arguments to pass to :command:`add_definitions`
- in the generated test project.
+The options specific to ``try_run`` are:
``COMPILE_OUTPUT_VARIABLE <var>``
Report the compile step build output in a given variable.
-``LINK_LIBRARIES <libs>...``
- .. versionadded:: 3.2
-
- Specify libraries to be linked in the generated project.
- The list of libraries may refer to system libraries and to
- :ref:`Imported Targets <Imported Targets>` from the calling project.
-
- If this option is specified, any ``-DLINK_LIBRARIES=...`` value
- given to the ``CMAKE_FLAGS`` option will be ignored.
-
-``LINK_OPTIONS <options>...``
- .. versionadded:: 3.14
-
- Specify link step options to pass to :command:`target_link_options` in the
- generated project.
-
``OUTPUT_VARIABLE <var>``
Report the compile build output and the output from running the executable
- in the given variable. This option exists for legacy reasons. Prefer
- ``COMPILE_OUTPUT_VARIABLE`` and ``RUN_OUTPUT_VARIABLE`` instead.
+ in the given variable. This option exists for legacy reasons and is only
+ supported by the old ``try_run`` signature.
+ Prefer ``COMPILE_OUTPUT_VARIABLE`` and ``RUN_OUTPUT_VARIABLE`` instead.
``RUN_OUTPUT_VARIABLE <var>``
Report the output from running the executable in a given variable.
+``RUN_OUTPUT_STDOUT_VARIABLE <var>``
+ .. versionadded:: 3.25
+
+ Report the output of stdout from running the executable in a given variable.
+
+``RUN_OUTPUT_STDERR_VARIABLE <var>``
+ .. versionadded:: 3.25
+
+ Report the output of stderr from running the executable in a given variable.
+
``WORKING_DIRECTORY <var>``
.. versionadded:: 3.20
Run the executable in the given directory. If no ``WORKING_DIRECTORY`` is
- specified, the executable will run in ``<bindir>``.
+ specified, the executable will run in ``<bindir>`` or the current build
+ directory.
+
+``ARGS <args>...``
+ Additional arguments to pass to the executable when running it.
Other Behavior Settings
^^^^^^^^^^^^^^^^^^^^^^^
@@ -110,6 +132,7 @@ These cache entries are:
In order to make cross compiling your project easier, use ``try_run``
only if really required. If you use ``try_run``, use the
+``RUN_OUTPUT_STDOUT_VARIABLE``, ``RUN_OUTPUT_STDERR_VARIABLE``,
``RUN_OUTPUT_VARIABLE`` or ``OUTPUT_VARIABLE`` options only if really
required. Using them will require that when cross-compiling, the cache
variables will have to be set manually to the output of the executable.
diff --git a/Help/command/while.rst b/Help/command/while.rst
index a4957c1..0bafae5 100644
--- a/Help/command/while.rst
+++ b/Help/command/while.rst
@@ -23,3 +23,11 @@ Per legacy, the :command:`endwhile` command admits
an optional ``<condition>`` argument.
If used, it must be a verbatim repeat of the argument of the opening
``while`` command.
+
+See Also
+^^^^^^^^
+
+ * :command:`break`
+ * :command:`continue`
+ * :command:`foreach`
+ * :command:`endwhile`
diff --git a/Help/cpack_gen/archive.rst b/Help/cpack_gen/archive.rst
index a77b615..9df3cc4 100644
--- a/Help/cpack_gen/archive.rst
+++ b/Help/cpack_gen/archive.rst
@@ -57,6 +57,12 @@ Variables specific to CPack Archive generator
.. versionadded:: 3.9
Per-component ``CPACK_ARCHIVE_<component>_FILE_NAME`` variables.
+.. variable:: CPACK_ARCHIVE_FILE_EXTENSION
+
+ .. versionadded:: 3.25
+
+ Package file extension. Default values are given in the list above.
+
.. variable:: CPACK_ARCHIVE_COMPONENT_INSTALL
Enable component packaging. If enabled (ON), then the archive generator
diff --git a/Help/cpack_gen/external.rst b/Help/cpack_gen/external.rst
index 4c083f0..b511319 100644
--- a/Help/cpack_gen/external.rst
+++ b/Help/cpack_gen/external.rst
@@ -207,8 +207,8 @@ following fields in the root:
set.
``buildConfig``
- The build configuration given to CPack with the ``-C`` option. Only present
- if this option is set.
+ The build configuration given to CPack with the :option:`cpack -C` option.
+ Only present if this option is set.
``defaultDirectoryPermissions``
The default directory permissions given in
diff --git a/Help/cpack_gen/freebsd.rst b/Help/cpack_gen/freebsd.rst
index f429bc5..faf8c74 100644
--- a/Help/cpack_gen/freebsd.rst
+++ b/Help/cpack_gen/freebsd.rst
@@ -62,8 +62,6 @@ the RPM information (e.g. package license).
- :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY` (this is always set
by CPack itself, if nothing else sets it explicitly).
- - :variable:`PROJECT_DESCRIPTION` (this can be set with the DESCRIPTION
- parameter for :command:`project`).
.. variable:: CPACK_FREEBSD_PACKAGE_DESCRIPTION
@@ -75,6 +73,10 @@ the RPM information (e.g. package license).
- :variable:`CPACK_DEBIAN_PACKAGE_DESCRIPTION` (this may be set already
for Debian packaging, so it is used as a fallback).
+ - :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY` (this is always set
+ by CPack itself, if nothing else sets it explicitly).
+ - :variable:`PROJECT_DESCRIPTION` (this can be set with the DESCRIPTION
+ parameter for :command:`project`).
.. variable:: CPACK_FREEBSD_PACKAGE_WWW
@@ -85,12 +87,12 @@ the RPM information (e.g. package license).
* Mandatory: YES
* Default:
- - :variable:`CMAKE_PROJECT_HOMEPAGE_URL`, or if that is not set,
- :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already
+ - :variable:`CPACK_PACKAGE_HOMEPAGE_URL`, or if that is not set,
+ - :variable:`CPACK_DEBIAN_PACKAGE_HOMEPAGE` (this may be set already
for Debian packaging, so it is used as a fallback).
.. versionadded:: 3.12
- The ``CMAKE_PROJECT_HOMEPAGE_URL`` variable.
+ The ``CPACK_PACKAGE_HOMEPAGE_URL`` variable.
.. variable:: CPACK_FREEBSD_PACKAGE_LICENSE
diff --git a/Help/cpack_gen/nuget.rst b/Help/cpack_gen/nuget.rst
index c980dd6..3bc73aa 100644
--- a/Help/cpack_gen/nuget.rst
+++ b/Help/cpack_gen/nuget.rst
@@ -162,6 +162,14 @@ List of CPack NuGet generator specific variables:
* Mandatory : NO
* Default : -
+.. variable:: CPACK_NUGET_PACKAGE_REQUIRE_LICENSE_ACCEPTANCE
+
+ When set to a true value, the user will be prompted to accept the license
+ before installing the package.
+
+ * Mandatory : NO
+ * Default : -
+
.. variable:: CPACK_NUGET_PACKAGE_ICON
CPACK_NUGET_<compName>_PACKAGE_ICON
diff --git a/Help/cpack_gen/rpm.rst b/Help/cpack_gen/rpm.rst
index 0d287fc..13b7255 100644
--- a/Help/cpack_gen/rpm.rst
+++ b/Help/cpack_gen/rpm.rst
@@ -972,7 +972,7 @@ For CMake projects SRPM package would be produced by executing::
Produced SRPM package is expected to be built with :manual:`cmake(1)` executable
and packaged with :manual:`cpack(1)` executable so CMakeLists.txt has to be
located in root source directory and must be able to generate binary rpm
- packages by executing ``cpack -G`` command. The two executables as well as
+ packages by executing :option:`cpack -G` command. The two executables as well as
rpmbuild must also be present when generating binary rpm packages from the
produced SRPM package.
diff --git a/Help/dev/experimental.rst b/Help/dev/experimental.rst
index 7638d22..adfa36f 100644
--- a/Help/dev/experimental.rst
+++ b/Help/dev/experimental.rst
@@ -7,6 +7,23 @@ See documentation on `CMake Development`_ for more information.
.. _`CMake Development`: README.rst
+Features are gated behind ``CMAKE_EXPERIMENTAL_`` variables which must be set
+to specific values in order to enable their gated behaviors. Note that the
+specific values will change over time to reinforce their experimental nature.
+When used, a warning will be generated to indicate that an experimental
+feature is in use and that the affected behavior in the project is not part of
+CMake's stability guarantees.
+
+C++20 Module APIs
+=================
+
+Variable: ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+Value: ``3c375311-a3c9-4396-a187-3227ef642046``
+
+In order to support C++20 modules, there are a number of behaviors that have
+CMake APIs to provide the required features to build and export them from a
+project.
+
C++20 Module Dependencies
=========================
@@ -40,13 +57,8 @@ dependencies to the file specified by the ``<DYNDEP_FILE>`` placeholder. The
``CMAKE_EXPERIMENTAL_CXX_SCANDEP_DEPFILE_FORMAT`` file may be set to ``msvc``
for scandep rules which use ``msvc``-style dependency reporting.
-For tools which need to know the file set the source belongs to, the
-``CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_<FILE_SET_TYPE>`` flag may
-be provided so that different source types can be distinguished prior to
-scanning.
-
The module dependencies should be written in the format described
-by the `P1689r4`_ paper.
+by the `P1689r5`_ paper.
Compiler writers may try out their scanning functionality using
the `cxx-modules-sandbox`_ test project, modified to set variables
@@ -73,5 +85,5 @@ the GCC documentation, but the relevant section for the purposes of CMake is:
-- GCC module mapper documentation
.. _`D1483r1`: https://mathstuf.fedorapeople.org/fortran-modules/fortran-modules.html
-.. _`P1689r4`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1689r4.html
+.. _`P1689r5`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html
.. _`cxx-modules-sandbox`: https://github.com/mathstuf/cxx-modules-sandbox
diff --git a/Help/envvar/CMAKE_GENERATOR.rst b/Help/envvar/CMAKE_GENERATOR.rst
index 3488b04..596e8f3 100644
--- a/Help/envvar/CMAKE_GENERATOR.rst
+++ b/Help/envvar/CMAKE_GENERATOR.rst
@@ -6,9 +6,9 @@ CMAKE_GENERATOR
.. include:: ENV_VAR.txt
Specifies the CMake default generator to use when no generator is supplied
-with ``-G``. If the provided value doesn't name a generator known by CMake,
-the internal default is used. Either way the resulting generator selection
-is stored in the :variable:`CMAKE_GENERATOR` variable.
+with :option:`-G <cmake -G>`. If the provided value doesn't name a generator
+known by CMake, the internal default is used. Either way the resulting
+generator selection is stored in the :variable:`CMAKE_GENERATOR` variable.
Some generators may be additionally configured using the environment
variables:
diff --git a/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst b/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
index b039845..e657904 100644
--- a/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
+++ b/Help/envvar/CMAKE_GENERATOR_PLATFORM.rst
@@ -6,5 +6,5 @@ CMAKE_GENERATOR_PLATFORM
.. include:: ENV_VAR.txt
Default value for :variable:`CMAKE_GENERATOR_PLATFORM` if no Cache entry
-is present and no value is specified by :manual:`cmake(1)` ``-A`` option.
+is present and no value is specified by :option:`cmake -A` option.
This value is only applied if :envvar:`CMAKE_GENERATOR` is set.
diff --git a/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst b/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
index 394dd88..03208e7 100644
--- a/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
+++ b/Help/envvar/CMAKE_GENERATOR_TOOLSET.rst
@@ -6,5 +6,5 @@ CMAKE_GENERATOR_TOOLSET
.. include:: ENV_VAR.txt
Default value for :variable:`CMAKE_GENERATOR_TOOLSET` if no Cache entry
-is present and no value is specified by :manual:`cmake(1)` ``-T`` option.
+is present and no value is specified by :option:`cmake -T` option.
This value is only applied if :envvar:`CMAKE_GENERATOR` is set.
diff --git a/Help/envvar/CTEST_PROGRESS_OUTPUT.rst b/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
index 8c29d7d..348acc6 100644
--- a/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
+++ b/Help/envvar/CTEST_PROGRESS_OUTPUT.rst
@@ -14,5 +14,5 @@ variable is not set or has a value that evaluates to false, output is reported
normally with each test having its own start and end lines logged to the
output.
-The ``--progress`` option to :manual:`ctest <ctest(1)>` overrides this
-environment variable if both are given.
+The :option:`--progress <ctest --progress>` option to :manual:`ctest <ctest(1)>`
+overrides this environment variable if both are given.
diff --git a/Help/envvar/DESTDIR.rst b/Help/envvar/DESTDIR.rst
index 94cae4a..414db12 100644
--- a/Help/envvar/DESTDIR.rst
+++ b/Help/envvar/DESTDIR.rst
@@ -20,8 +20,9 @@ The packaging tool may then construct the package from the content of the
See the :variable:`CMAKE_INSTALL_PREFIX` variable to control the
installation prefix when configuring a build tree. Or, when using
-the :manual:`cmake(1)` command-line tool's ``--install`` mode,
-one may specify a different prefix using the ``--prefix`` option.
+the :manual:`cmake(1)` command-line tool's :option:`--install <cmake --install>`
+mode, one may specify a different prefix using the
+:option:`--prefix <cmake --prefix>` option.
.. note::
diff --git a/Help/generator/Green Hills MULTI.rst b/Help/generator/Green Hills MULTI.rst
index 1b4739b..7a5993a 100644
--- a/Help/generator/Green Hills MULTI.rst
+++ b/Help/generator/Green Hills MULTI.rst
@@ -28,12 +28,12 @@ Otherwise the ``primaryTarget`` will be composed from the values of :variable:`C
and ``GHS_TARGET_PLATFORM``. Defaulting to the value of ``arm_integrity.tgt``
* The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
- via the :manual:`cmake(1)` ``-A`` option.
+ via the :option:`cmake -A` option.
| Typical values of ``arm``, ``ppc``, ``86``, etcetera, are used.
-* The variable ``GHS_TARGET_PLATFORM`` may be set, perhaps via the :manual:`cmake(1)`
- ``-D`` option.
+* The variable ``GHS_TARGET_PLATFORM`` may be set, perhaps via the :option:`cmake -D`
+ option.
| Defaults to ``integrity``.
| Usual values are ``integrity``, ``threadx``, ``uvelosity``, ``velosity``,
@@ -55,11 +55,11 @@ The generator searches for the latest compiler or can be given a location to use
``GHS_TOOLSET_ROOT`` is the directory that is checked for the latest compiler.
* The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
- via the :manual:`cmake(1)` ``-T`` option, to specify the location of the toolset.
+ via the :option:`cmake -T` option, to specify the location of the toolset.
Both absolute and relative paths are valid. Paths are relative to ``GHS_TOOLSET_ROOT``.
-* The variable ``GHS_TOOLSET_ROOT`` may be set, perhaps via the :manual:`cmake(1)`
- ``-D`` option.
+* The variable ``GHS_TOOLSET_ROOT`` may be set, perhaps via the :option:`cmake -D`
+ option.
| Root path for toolset searches and relative paths.
| Defaults to ``C:/ghs`` in Windows or ``/usr/ghs`` in Linux.
diff --git a/Help/generator/Ninja Multi-Config.rst b/Help/generator/Ninja Multi-Config.rst
index e5ce4f5..ae075ed 100644
--- a/Help/generator/Ninja Multi-Config.rst
+++ b/Help/generator/Ninja Multi-Config.rst
@@ -20,8 +20,8 @@ are intended to be run with ``ninja -f build-<Config>.ninja``. A
: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
-use ``build.ninja``.
+to build. If no :option:`--config <cmake --config>` argument is specified,
+:option:`cmake --build .<cmake --build>` will use ``build.ninja``.
Each ``build-<Config>.ninja`` file contains ``<target>`` targets as well as
``<target>:<Config>`` targets, where ``<Config>`` is the same as the
diff --git a/Help/generator/Visual Studio 10 2010.rst b/Help/generator/Visual Studio 10 2010.rst
index 9ec33c3..66cd25f 100644
--- a/Help/generator/Visual Studio 10 2010.rst
+++ b/Help/generator/Visual Studio 10 2010.rst
@@ -27,7 +27,7 @@ The default target platform name (architecture) is ``Win32``.
.. versionadded:: 3.1
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
- via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+ via the :option:`cmake -A` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 10 2010" -A Win32``
@@ -49,4 +49,4 @@ Toolset Selection
The ``v100`` toolset that comes with Visual Studio 10 2010 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+via the :option:`cmake -T` option, to specify another toolset.
diff --git a/Help/generator/Visual Studio 11 2012.rst b/Help/generator/Visual Studio 11 2012.rst
index 3952228..adbd1af 100644
--- a/Help/generator/Visual Studio 11 2012.rst
+++ b/Help/generator/Visual Studio 11 2012.rst
@@ -20,7 +20,7 @@ The default target platform name (architecture) is ``Win32``.
.. versionadded:: 3.1
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
- via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+ via the :option:`cmake -A` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 11 2012" -A Win32``
@@ -47,4 +47,4 @@ Toolset Selection
The ``v110`` toolset that comes with Visual Studio 11 2012 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+via the :option:`cmake -T` option, to specify another toolset.
diff --git a/Help/generator/Visual Studio 12 2013.rst b/Help/generator/Visual Studio 12 2013.rst
index 54a4d7e..3dbcfe6 100644
--- a/Help/generator/Visual Studio 12 2013.rst
+++ b/Help/generator/Visual Studio 12 2013.rst
@@ -20,7 +20,7 @@ The default target platform name (architecture) is ``Win32``.
.. versionadded:: 3.1
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
- via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+ via the :option:`cmake -A` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 12 2013" -A Win32``
@@ -42,7 +42,7 @@ Toolset Selection
The ``v120`` toolset that comes with Visual Studio 12 2013 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+via the :option:`cmake -T` option, to specify another toolset.
.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
By default this generator uses the 32-bit variant even on a 64-bit host.
diff --git a/Help/generator/Visual Studio 14 2015.rst b/Help/generator/Visual Studio 14 2015.rst
index d704ab2..af7dfaa 100644
--- a/Help/generator/Visual Studio 14 2015.rst
+++ b/Help/generator/Visual Studio 14 2015.rst
@@ -18,7 +18,7 @@ Platform Selection
The default target platform name (architecture) is ``Win32``.
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
-via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+via the :option:`cmake -A` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 14 2015" -A Win32``
@@ -40,7 +40,7 @@ Toolset Selection
The ``v140`` toolset that comes with Visual Studio 14 2015 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+via the :option:`cmake -T` option, to specify another toolset.
.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
By default this generator uses the 32-bit variant even on a 64-bit host.
diff --git a/Help/generator/Visual Studio 15 2017.rst b/Help/generator/Visual Studio 15 2017.rst
index 912afad..6bcc033 100644
--- a/Help/generator/Visual Studio 15 2017.rst
+++ b/Help/generator/Visual Studio 15 2017.rst
@@ -26,7 +26,7 @@ Platform Selection
The default target platform name (architecture) is ``Win32``.
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
-via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+via the :option:`cmake -A` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 15 2017" -A Win32``
@@ -49,7 +49,7 @@ Toolset Selection
The ``v141`` toolset that comes with Visual Studio 15 2017 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+via the :option:`cmake -T` option, to specify another toolset.
.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
By default this generator uses the 32-bit variant even on a 64-bit host.
diff --git a/Help/generator/Visual Studio 16 2019.rst b/Help/generator/Visual Studio 16 2019.rst
index 6cefe6d..2918a6e 100644
--- a/Help/generator/Visual Studio 16 2019.rst
+++ b/Help/generator/Visual Studio 16 2019.rst
@@ -25,7 +25,7 @@ The default target platform name (architecture) is that of the host
and is provided in the :variable:`CMAKE_VS_PLATFORM_NAME_DEFAULT` variable.
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
-via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+via the :option:`cmake -A` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 16 2019" -A Win32``
@@ -38,7 +38,7 @@ Toolset Selection
The ``v142`` toolset that comes with Visual Studio 16 2019 is selected by
default. The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+via the :option:`cmake -T` option, to specify another toolset.
.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
By default this generator uses the 64-bit variant on x64 hosts and
diff --git a/Help/generator/Visual Studio 17 2022.rst b/Help/generator/Visual Studio 17 2022.rst
index edf9d60..ab101ac 100644
--- a/Help/generator/Visual Studio 17 2022.rst
+++ b/Help/generator/Visual Studio 17 2022.rst
@@ -25,7 +25,7 @@ The default target platform name (architecture) is that of the host
and is provided in the :variable:`CMAKE_VS_PLATFORM_NAME_DEFAULT` variable.
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
-via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+via the :option:`cmake -A` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 17 2022" -A Win32``
@@ -38,7 +38,7 @@ Toolset Selection
The ``v143`` toolset that comes with VS 17 2022 is selected by default.
The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+via the :option:`cmake -T` option, to specify another toolset.
.. |VS_TOOLSET_HOST_ARCH_DEFAULT| replace::
By default this generator uses the 64-bit variant on x64 hosts and
diff --git a/Help/generator/Visual Studio 9 2008.rst b/Help/generator/Visual Studio 9 2008.rst
index 644f936..3434956 100644
--- a/Help/generator/Visual Studio 9 2008.rst
+++ b/Help/generator/Visual Studio 9 2008.rst
@@ -10,7 +10,7 @@ The default target platform name (architecture) is ``Win32``.
.. versionadded:: 3.1
The :variable:`CMAKE_GENERATOR_PLATFORM` variable may be set, perhaps
- via the :manual:`cmake(1)` ``-A`` option, to specify a target platform
+ via the :option:`cmake -A` option, to specify a target platform
name (architecture). For example:
* ``cmake -G "Visual Studio 9 2008" -A Win32``
diff --git a/Help/generator/Xcode.rst b/Help/generator/Xcode.rst
index e4900a1..fc7eea1 100644
--- a/Help/generator/Xcode.rst
+++ b/Help/generator/Xcode.rst
@@ -13,7 +13,7 @@ Toolset and Build System Selection
By default Xcode is allowed to select its own default toolchain.
The :variable:`CMAKE_GENERATOR_TOOLSET` option may be set, perhaps
-via the :manual:`cmake(1)` ``-T`` option, to specify another toolset.
+via the :option:`cmake -T` option, to specify another toolset.
.. versionadded:: 3.19
This generator supports toolset specification using one of these forms:
diff --git a/Help/guide/ide-integration/index.rst b/Help/guide/ide-integration/index.rst
index 8473481..e198789 100644
--- a/Help/guide/ide-integration/index.rst
+++ b/Help/guide/ide-integration/index.rst
@@ -47,8 +47,9 @@ does, and present the user with the presets listed in the file. Users should be
able to see (and possibly edit) the CMake cache variables, environment
variables, and command line options that are defined for a given preset. The
IDE should then construct the list of appropriate :manual:`cmake(1)` command
-line arguments based on these settings, rather than using the ``--preset=``
-option directly. The ``--preset=`` option is intended only as a convenient
+line arguments based on these settings, rather than using the
+:option:`--preset= <cmake --preset>` option directly. The
+:option:`--preset= <cmake --preset>` option is intended only as a convenient
frontend for command line users, and should not be used by the IDE.
For example, if a preset named ``ninja`` specifies ``Ninja`` as the generator
@@ -66,10 +67,9 @@ run:
cmake -S /path/to/source -B /path/to/source/build -G Ninja
In cases where a preset contains lots of cache variables, and passing all of
-them as ``-D`` flags would cause the command line length limit of the platform
-to be exceeded, the IDE should instead construct a temporary cache script and
-pass it with the ``-C`` flag. See :ref:`CMake Options` for details on how the
-``-C`` flag is used.
+them as :option:`-D <cmake -D>` flags would cause the command line length limit
+of the platform to be exceeded, the IDE should instead construct a temporary
+cache script and pass it with the :option:`-C <cmake -C>` flag.
While reading, parsing, and evaluating the contents of ``CMakePresets.json`` is
straightforward, it is not trivial. In addition to the documentation, IDE
@@ -110,8 +110,9 @@ Building
If a Makefile or Ninja generator is used to generate the build tree, it is not
recommended to invoke ``make`` or ``ninja`` directly. Instead, it is
-recommended that the IDE invoke :manual:`cmake(1)` with the ``--build``
-argument, which will in turn invoke the appropriate build tool.
+recommended that the IDE invoke :manual:`cmake(1)` with the
+:option:`--build <cmake --build>` argument, which will in turn invoke the
+appropriate build tool.
If an IDE project generator is used, such as :generator:`Xcode` or one of the
Visual Studio generators, and the IDE understands the project format used, the
diff --git a/Help/guide/tutorial/A Basic Starting Point.rst b/Help/guide/tutorial/A Basic Starting Point.rst
index cf1ec01..3dac68a 100644
--- a/Help/guide/tutorial/A Basic Starting Point.rst
+++ b/Help/guide/tutorial/A Basic Starting Point.rst
@@ -1,34 +1,81 @@
Step 1: A Basic Starting Point
==============================
-The most basic project is an executable built from source code files.
-For simple projects, a three line ``CMakeLists.txt`` file is all that is
-required. This will be the starting point for our tutorial. Create a
-``CMakeLists.txt`` file in the ``Step1`` directory that looks like:
-
-.. code-block:: cmake
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-start
-
- cmake_minimum_required(VERSION 3.10)
+Where do I start with CMake? This step will provide an introduction to some of
+CMake's basic syntax, commands, and variables. As these concepts are
+introduced, we will work through three exercises and create a simple CMake
+project.
+
+Each exercise in this step will start with some background information. Then, a
+goal and list of helpful resources are provided. Each file in the
+``Files to Edit`` section is in the ``Step1`` directory and contains one or
+more ``TODO`` comments. Each ``TODO`` represents a line or two of code to
+change or add. The ``TODO`` s are intended to be completed in numerical order,
+first complete ``TODO 1`` then ``TODO 2``, etc. The ``Getting Started``
+section will give some helpful hints and guide you through the exercise. Then
+the ``Build and Run`` section will walk step-by-step through how to build and
+test the exercise. Finally, at the end of each exercise the intended solution
+is discussed.
+
+Also note that each step in the tutorial builds on the next. So, for example,
+the starting code for ``Step2`` is the complete solution to ``Step1``.
+
+Exercise 1 - Building a Basic Project
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+The most basic CMake project is an executable built from a single source code
+file. For simple projects like this, a ``CMakeLists.txt`` file with three
+commands is all that is required.
+
+**Note:** Although upper, lower and mixed case commands are supported by CMake,
+lower case commands are preferred and will be used throughout the tutorial.
+
+Any project's top most CMakeLists.txt must start by specifying a minimum CMake
+version using the :command:`cmake_minimum_required` command. This establishes
+policy settings and ensures that the following CMake functions are run with a
+compatible version of CMake.
+
+To start a project, we use the :command:`project` command to set the project
+name. This call is required with every project and should be called soon after
+:command:`cmake_minimum_required`. As we will see later, this command can
+also be used to specify other project level information such as the language
+or version number.
+
+Finally, the :command:`add_executable` command tells CMake to create an
+executable using the specified source code files.
+
+Goal
+----
+
+Understand how to create a simple CMake project.
+
+Helpful Resources
+-----------------
+
+* :command:`add_executable`
+* :command:`cmake_minimum_required`
+* :command:`project`
+
+Files to Edit
+-------------
- # set the project name
- project(Tutorial)
+* ``CMakeLists.txt``
- # add the executable
- add_executable(Tutorial tutorial.cxx)
+Getting Started
+----------------
+The source code for ``tutorial.cxx`` is provided in the
+``Help/guide/tutorial/Step1`` directory and can be used to compute the square
+root of a number. This file does not need to be edited in this step.
-Note that this example uses lower case commands in the ``CMakeLists.txt`` file.
-Upper, lower, and mixed case commands are supported by CMake. The source
-code for ``tutorial.cxx`` is provided in the ``Step1`` directory and can be
-used to compute the square root of a number.
+In the same directory is a ``CMakeLists.txt`` file which you will complete.
+Start with ``TODO 1`` and work through ``TODO 3``.
Build and Run
-------------
-That's all that is needed - we can build and run our project now! First, run
-the :manual:`cmake <cmake(1)>` executable or the
+Once ``TODO 1`` through ``TODO 3`` have been completed, we are ready to build
+and run our project! First, run the :manual:`cmake <cmake(1)>` executable or the
:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
with your chosen build tool.
@@ -40,8 +87,9 @@ build directory:
mkdir Step1_build
-Next, navigate to the build directory and run CMake to configure the project
-and generate a native build system:
+Next, navigate to that build directory and run
+:manual:`cmake <cmake(1)>` to configure the project and generate a native build
+system:
.. code-block:: console
@@ -62,114 +110,352 @@ Finally, try to use the newly built ``Tutorial`` with these commands:
Tutorial 10
Tutorial
+Solution
+--------
-Adding a Version Number and Configured Header File
---------------------------------------------------
+As mentioned above, a three line ``CMakeLists.txt`` is all that we need to get
+up and running. The first line is to use :command:`cmake_minimum_required` to
+set the CMake version as follows:
-The first feature we will add is to provide our executable and project with a
-version number. While we could do this exclusively in the source code, using
-``CMakeLists.txt`` provides more flexibility.
+.. raw:: html
-First, modify the ``CMakeLists.txt`` file to use the :command:`project` command
-to set the project name and version number.
+ <details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step2/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-project-VERSION
+ :caption: TODO 1: CMakeLists.txt
+ :name: CMakeLists.txt-cmake_minimum_required
:language: cmake
- :end-before: # specify the C++ standard
+ :end-before: # set the project name and version
-Then, configure a header file to pass the version number to the source
-code:
+.. raw:: html
-.. literalinclude:: Step2/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-configure_file
- :language: cmake
- :start-after: # to the source code
- :end-before: # add the executable
+ </details>
+
+The next step to make a basic project is to use the :command:`project`
+command as follows to set the project name:
+
+.. raw:: html
+
+ <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+ :caption: TODO 2: CMakeLists.txt
+ :name: CMakeLists.txt-project
+
+ project(Tutorial)
+
+.. raw:: html
-Since the configured file will be written into the binary tree, we
-must add that directory to the list of paths to search for include
-files. Add the following lines to the end of the ``CMakeLists.txt`` file:
+ </details>
+
+The last command to call for a basic project is
+:command:`add_executable`. We call it as follows:
+
+.. raw:: html
+
+ <details><summary>TODO 3: Click to show/hide answer</summary>
.. literalinclude:: Step2/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-target_include_directories
+ :caption: TODO 3: CMakeLists.txt
+ :name: CMakeLists.txt-add_executable
:language: cmake
- :start-after: # so that we will find TutorialConfig.h
+ :start-after: # add the executable
+ :end-before: # TODO 9:
-Using your favorite editor, create ``TutorialConfig.h.in`` in the source
-directory with the following contents:
+.. raw:: html
-.. literalinclude:: Step2/TutorialConfig.h.in
- :caption: TutorialConfig.h.in
- :name: TutorialConfig.h.in
- :language: c++
+ </details>
-When CMake configures this header file the values for
-``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will be
-replaced.
+Exercise 2 - Specifying the C++ Standard
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-Next modify ``tutorial.cxx`` to include the configured header file,
-``TutorialConfig.h``.
+CMake has some special variables that are either created behind the scenes or
+have meaning to CMake when set by project code. Many of these variables start
+with ``CMAKE_``. Avoid this naming convention when creating variables for your
+projects. Two of these special user settable variables are
+:variable:`CMAKE_CXX_STANDARD` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`.
+These may be used together to specify the C++ standard needed to build the
+project.
-Finally, let's print out the executable name and version number by updating
-``tutorial.cxx`` as follows:
+Goal
+----
-.. literalinclude:: Step2/tutorial.cxx
- :caption: tutorial.cxx
- :name: tutorial.cxx-print-version
- :language: c++
- :start-after: {
- :end-before: // convert input to double
+Add a feature that requires C++11.
+
+Helpful Resources
+-----------------
+
+* :variable:`CMAKE_CXX_STANDARD`
+* :variable:`CMAKE_CXX_STANDARD_REQUIRED`
+* :command:`set`
+
+Files to Edit
+-------------
-Specify the C++ Standard
--------------------------
+* ``CMakeLists.txt``
+* ``tutorial.cxx``
-Next let's add some C++11 features to our project by replacing ``atof`` with
-``std::stod`` in ``tutorial.cxx``. At the same time, remove
-``#include <cstdlib>``.
+Getting Started
+---------------
+
+Continue editing files in the ``Step1`` directory. Start with ``TODO 4`` and
+complete through ``TODO 6``.
+
+First, edit ``tutorial.cxx`` by adding a feature that requires C++11. Then
+update ``CMakeLists.txt`` to require C++11.
+
+Build and Run
+-------------
+
+Let's build our project again. Since we already created a build directory and
+ran CMake for Exercise 1, we can skip to the build step:
+
+.. code-block:: console
+
+ cd Step1_build
+ cmake --build .
+
+Now we can try to use the newly built ``Tutorial`` with same commands as
+before:
+
+.. code-block:: console
+
+ Tutorial 4294967296
+ Tutorial 10
+ Tutorial
+
+Solution
+--------
+
+We start by adding some C++11 features to our project by replacing
+``atof`` with ``std::stod`` in ``tutorial.cxx``. This looks like
+the following:
+
+.. raw:: html
+
+ <details><summary>TODO 4: Click to show/hide answer</summary>
.. literalinclude:: Step2/tutorial.cxx
- :caption: tutorial.cxx
+ :caption: TODO 4: tutorial.cxx
:name: tutorial.cxx-cxx11
:language: c++
:start-after: // convert input to double
- :end-before: // calculate square root
+ :end-before: // TODO 12:
+
+.. raw:: html
+
+ </details>
+
+To complete ``TODO 5``, simply remove ``#include <cstdlib>``.
We will need to explicitly state in the CMake code that it should use the
-correct flags. The easiest way to enable support for a specific C++ standard
-in CMake is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this
-tutorial, set the :variable:`CMAKE_CXX_STANDARD` variable in the
-``CMakeLists.txt`` file to ``11`` and :variable:`CMAKE_CXX_STANDARD_REQUIRED`
-to ``True``. Make sure to add the ``CMAKE_CXX_STANDARD`` declarations above the
-call to ``add_executable``.
+correct flags. One way to enable support for a specific C++ standard in CMake
+is by using the :variable:`CMAKE_CXX_STANDARD` variable. For this tutorial, set
+the :variable:`CMAKE_CXX_STANDARD` variable in the ``CMakeLists.txt`` file to
+``11`` and :variable:`CMAKE_CXX_STANDARD_REQUIRED` to ``True``. Make sure to
+add the :variable:`CMAKE_CXX_STANDARD` declarations above the call to
+:command:`add_executable`.
+
+.. raw:: html
+
+ <details><summary>TODO 6: Click to show/hide answer</summary>
.. literalinclude:: Step2/CMakeLists.txt
- :caption: CMakeLists.txt
+ :caption: TODO 6: CMakeLists.txt
:name: CMakeLists.txt-CXX_STANDARD
:language: cmake
- :end-before: # configure a header file to pass some of the CMake settings
+ :start-after: # specify the C++ standard
+ :end-before: # TODO 7:
+
+.. raw:: html
-Rebuild
--------
+ </details>
-Let's build our project again. We already created a build directory and ran
-CMake, so we can skip to the build step:
+Exercise 3 - Adding a Version Number and Configured Header File
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Sometimes it may be useful to have a variable that is defined in your
+``CMakelists.txt`` file also be available in your source code. In this case, we
+would like to print the project version.
+
+One way to accomplish this is by using a configured header file. We create an
+input file with one or more variables to replace. These variables have special
+syntax which looks like ``@VAR@``.
+Then, we use the :command:`configure_file` command to copy the input file to a
+given output file and replace these variables with the current value of ``VAR``
+in the ``CMakelists.txt`` file.
+
+While we could edit the version directly in the source code, using this
+feature is preferred since it creates a single source of truth and avoids
+duplication.
+
+Goal
+----
+
+Define and report the project's version number.
+
+Helpful Resources
+-----------------
+
+* :variable:`<PROJECT-NAME>_VERSION_MAJOR`
+* :variable:`<PROJECT-NAME>_VERSION_MINOR`
+* :command:`configure_file`
+* :command:`target_include_directories`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``tutorial.cxx``
+
+Getting Started
+---------------
+
+Continue to edit files from ``Step1``. Start on ``TODO 7`` and complete through
+``TODO 12``. In this exercise, we start by adding a project version number in
+``CMakeLists.txt``. In that same file, use :command:`configure_file` to copy a
+given input file to an output file and substitute some variable values in the
+input file content.
+
+Next, create an input header file ``TutorialConfig.h.in`` defining version
+numbers which will accept variables passed from :command:`configure_file`.
+
+Finally, update ``tutorial.cxx`` to print out its version number.
+
+Build and Run
+-------------
+
+Let's build our project again. As before, we already created a build directory
+and ran CMake so we can skip to the build step:
.. code-block:: console
cd Step1_build
cmake --build .
-Now we can try to use the newly built ``Tutorial`` with same commands as before:
+Verify that the version number is now reported when running the executable
+without any arguments.
-.. code-block:: console
+Solution
+--------
- Tutorial 4294967296
- Tutorial 10
- Tutorial
+In this exercise, we improve our executable by printing a version number.
+While we could do this exclusively in the source code, using ``CMakeLists.txt``
+lets us maintain a single source of data for the version number.
+
+First, we modify the ``CMakeLists.txt`` file to use the
+:command:`project` command to set both the project name and version number.
+When the :command:`project` command is called, CMake defines
+``Tutorial_VERSION_MAJOR`` and ``Tutorial_VERSION_MINOR`` behind the scenes.
+
+.. raw:: html
+
+ <details><summary>TODO 7: Click to show/hide answer</summary>
+
+.. literalinclude:: Step2/CMakeLists.txt
+ :caption: TODO 7: CMakeLists.txt
+ :name: CMakeLists.txt-project-VERSION
+ :language: cmake
+ :start-after: # set the project name and version
+ :end-before: # specify the C++ standard
+
+.. raw:: html
+
+ </details>
+
+Then we used :command:`configure_file` to copy the input file with the
+specified CMake variables replaced:
+
+.. raw:: html
+
+ <details><summary>TODO 8: Click to show/hide answer</summary>
+
+.. literalinclude:: Step2/CMakeLists.txt
+ :caption: TODO 8: CMakeLists.txt
+ :name: CMakeLists.txt-configure_file
+ :language: cmake
+ :start-after: # to the source code
+ :end-before: # TODO 8:
+
+.. raw:: html
+
+ </details>
+
+Since the configured file will be written into the project binary
+directory, we must add that directory to the list of paths to search for
+include files.
+
+**Note:** Throughout this tutorial, we will refer to the project build and
+the project binary directory interchangeably. These are the same and are not
+meant to refer to a `bin/` directory.
+
+We used :command:`target_include_directories` to specify
+where the executable target should look for include files.
+
+.. raw:: html
+
+ <details><summary>TODO 9: Click to show/hide answer</summary>
+
+.. literalinclude:: Step2/CMakeLists.txt
+ :caption: TODO 9: CMakeLists.txt
+ :name: CMakeLists.txt-target_include_directories
+ :language: cmake
+ :start-after: # so that we will find TutorialConfig.h
+
+.. raw:: html
+
+ </details>
+
+``TutorialConfig.h.in`` is the input header file to be configured.
+When :command:`configure_file` is called from our ``CMakeLists.txt``, the
+values for ``@Tutorial_VERSION_MAJOR@`` and ``@Tutorial_VERSION_MINOR@`` will
+be replaced with the corresponding version numbers from the project in
+``TutorialConfig.h``.
+
+.. raw:: html
+
+ <details><summary>TODO 10: Click to show/hide answer</summary>
+
+.. literalinclude:: Step2/TutorialConfig.h.in
+ :caption: TODO 10: TutorialConfig.h.in
+ :name: TutorialConfig.h.in
+ :language: c++
+ :end-before: // TODO 13:
+
+.. raw:: html
+
+ </details>
+
+Next, we need to modify ``tutorial.cxx`` to include the configured header file,
+``TutorialConfig.h``.
+
+.. raw:: html
+
+ <details><summary>TODO 11: Click to show/hide answer</summary>
+
+.. code-block:: c++
+ :caption: TODO 11: tutorial.cxx
+
+ #include "TutorialConfig.h"
+
+.. raw:: html
+
+ </details>
+
+Finally, we print out the executable name and version number by updating
+``tutorial.cxx`` as follows:
+
+.. raw:: html
+
+ <details><summary>TODO 12: Click to show/hide answer</summary>
+
+.. literalinclude:: Step2/tutorial.cxx
+ :caption: TODO 12 : tutorial.cxx
+ :name: tutorial.cxx-print-version
+ :language: c++
+ :start-after: {
+ :end-before: // convert input to double
+
+.. raw:: html
-Check that the version number is now reported when running the executable without
-any arguments.
+ </details>
diff --git a/Help/guide/tutorial/Adding Generator Expressions.rst b/Help/guide/tutorial/Adding Generator Expressions.rst
index 7fcc97f..0efce8d 100644
--- a/Help/guide/tutorial/Adding Generator Expressions.rst
+++ b/Help/guide/tutorial/Adding Generator Expressions.rst
@@ -1,4 +1,4 @@
-Step 10: Adding Generator Expressions
+Step 4: Adding Generator Expressions
=====================================
:manual:`Generator expressions <cmake-generator-expressions(7)>` are evaluated
@@ -37,16 +37,16 @@ instead of using :variable:`CMAKE_CXX_STANDARD`.
So the following code:
-.. literalinclude:: Step10/CMakeLists.txt
+.. literalinclude:: Step4/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-CXX_STANDARD-variable-remove
:language: cmake
:start-after: project(Tutorial VERSION 1.0)
- :end-before: # control where the static and shared libraries are built so that on windows
+ :end-before: # should we use our own math functions
Would be replaced with:
-.. literalinclude:: Step11/CMakeLists.txt
+.. literalinclude:: Step5/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-cxx_std-feature
:language: cmake
@@ -69,12 +69,12 @@ warning flags vary based on the compiler we use the ``COMPILE_LANG_AND_ID``
generator expression to control which flags to apply given a language and a set
of compiler ids as seen below:
-.. literalinclude:: Step11/CMakeLists.txt
+.. literalinclude:: Step5/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-target_compile_options-genex
:language: cmake
:start-after: # the BUILD_INTERFACE genex
- :end-before: # control where the static and shared libraries are built so that on windows
+ :end-before: # should we use our own math functions
Looking at this we see that the warning flags are encapsulated inside a
``BUILD_INTERFACE`` condition. This is done so that consumers of our installed
diff --git a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
index c6e0fd0..45d5976 100644
--- a/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
+++ b/Help/guide/tutorial/Adding Support for a Testing Dashboard.rst
@@ -1,4 +1,4 @@
-Step 8: Adding Support for a Testing Dashboard
+Step 6: Adding Support for a Testing Dashboard
==============================================
Adding support for submitting our test results to a dashboard is simple. We
@@ -9,21 +9,21 @@ we include the :module:`CTest` module in our top-level ``CMakeLists.txt``.
Replace:
-.. code-block:: cmake
+.. literalinclude:: Step6/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-enable_testing-remove
-
- # enable testing
- enable_testing()
+ :language: cmake
+ :start-after: # enable testing
+ :end-before: # does the application run
With:
-.. code-block:: cmake
+.. literalinclude:: Step7/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-include-CTest
-
- # enable dashboard scripting
- include(CTest)
+ :language: cmake
+ :start-after: # enable testing
+ :end-before: # does the application run
The :module:`CTest` module will automatically call ``enable_testing()``, so we
can remove it from our CMake files.
@@ -46,7 +46,7 @@ downloaded from the ``Settings`` page of the project on the CDash
instance that will host and display the test results. Once downloaded from
CDash, the file should not be modified locally.
-.. literalinclude:: Step9/CTestConfig.cmake
+.. literalinclude:: Step7/CTestConfig.cmake
:caption: CTestConfig.cmake
:name: CTestConfig.cmake
:language: cmake
diff --git a/Help/guide/tutorial/Adding System Introspection.rst b/Help/guide/tutorial/Adding System Introspection.rst
index 8db0cb8..4f3e808 100644
--- a/Help/guide/tutorial/Adding System Introspection.rst
+++ b/Help/guide/tutorial/Adding System Introspection.rst
@@ -1,4 +1,4 @@
-Step 5: Adding System Introspection
+Step 7: Adding System Introspection
===================================
Let us consider adding some code to our project that depends on features the
@@ -15,7 +15,7 @@ these functions using the :module:`CheckCXXSourceCompiles` module in
Add the checks for ``log`` and ``exp`` to ``MathFunctions/CMakeLists.txt``,
after the call to :command:`target_include_directories`:
-.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-check_cxx_source_compiles
:language: cmake
@@ -25,7 +25,7 @@ after the call to :command:`target_include_directories`:
If available, use :command:`target_compile_definitions` to specify
``HAVE_LOG`` and ``HAVE_EXP`` as ``PRIVATE`` compile definitions.
-.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step8/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-target_compile_definitions
:language: cmake
@@ -37,7 +37,7 @@ compute the square root in the ``mysqrt`` function. Add the following code to
the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the
``#endif`` before returning the result!):
-.. literalinclude:: Step6/MathFunctions/mysqrt.cxx
+.. literalinclude:: Step8/MathFunctions/mysqrt.cxx
:caption: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-ifdef
:language: c++
@@ -46,7 +46,7 @@ the ``mysqrt`` function in ``MathFunctions/mysqrt.cxx`` (don't forget the
We will also need to modify ``mysqrt.cxx`` to include ``cmath``.
-.. literalinclude:: Step6/MathFunctions/mysqrt.cxx
+.. literalinclude:: Step8/MathFunctions/mysqrt.cxx
:caption: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-include-cmath
:language: c++
diff --git a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
index a8e914e..b521896 100644
--- a/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
+++ b/Help/guide/tutorial/Adding Usage Requirements for a Library.rst
@@ -1,52 +1,142 @@
Step 3: Adding Usage Requirements for a Library
===============================================
-Usage requirements allow for far better control over a library or executable's
-link and include line while also giving more control over the transitive
-property of targets inside CMake. The primary commands that leverage usage
-requirements are:
-
- - :command:`target_compile_definitions`
- - :command:`target_compile_options`
- - :command:`target_include_directories`
- - :command:`target_link_libraries`
-
-Let's refactor our code from :guide:`tutorial/Adding a Library` to use the
-modern CMake approach of usage requirements. We first state that anybody
-linking to ``MathFunctions`` needs to include the current source directory,
-while ``MathFunctions`` itself doesn't. So this can become an ``INTERFACE``
-usage requirement.
-
-Remember ``INTERFACE`` means things that consumers require but the producer
-doesn't. Add the following lines to the end of
-``MathFunctions/CMakeLists.txt``:
+Exercise 1 - Adding Usage Requirements for a Library
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Usage requirements allow for far better control over a library or
+executable's link and include line while also giving more control over the
+transitive property of targets inside CMake. The primary commands that
+leverage usage requirements are:
+
+* :command:`target_compile_definitions`
+* :command:`target_compile_options`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+
+Goal
+----
+
+Add usage requirements for a library.
+
+Helpful Materials
+-----------------
+
+* :command:`target_include_directories`
+* :variable:`CMAKE_CURRENT_SOURCE_DIR`
+
+Files to Edit
+-------------
+
+* ``MathFunctions/CMakeLists.txt``
+* ``CMakeLists.txt``
+
+Getting Started
+---------------
+
+In this exercise, we will refactor our code from
+:guide:`tutorial/Adding a Library` to use the modern CMake approach. We will
+let our library define its own usage requirements so they are passed
+transitively to other targets as necessary. In this case, ``MathFunctions``
+will specify any needed include directories itself. Then, the consuming target
+``Tutorial`` simply needs to link to ``MathFunctions`` and not worry about
+any additional include directories.
+
+The starting source code is provided in the ``Step3`` directory. In this
+exercise, complete ``TODO 1`` through ``TODO 3``.
+
+First, add a call to :command:`target_include_directories` in
+``MathFunctions/CMakeLists``. Remember that
+:variable:`CMAKE_CURRENT_SOURCE_DIR` is the path to the source directory
+currently being processed.
+
+Then, update (and simplify!) the call to
+:command:`target_include_directories` in the top-level ``CMakeLists.txt``.
+
+Build and Run
+-------------
+
+Make a new directory called ``Step3_build``, run the :manual:`cmake
+<cmake(1)>` executable or the :manual:`cmake-gui <cmake-gui(1)>` to
+configure the project and then build it with your chosen build tool or by
+using ``cmake --build .`` from the build directory. Here's a refresher of
+what that looks like from the command line:
+
+.. code-block:: console
+
+ mkdir Step3_build
+ cd Step3_build
+ cmake ../Step3
+ cmake --build .
+
+Next, use the newly built ``Tutorial`` and verify that it is working as
+expected.
+
+Solution
+--------
+
+Let's update the code from the previous step to use the modern CMake
+approach of usage requirements.
+
+We want to state that anybody linking to ``MathFunctions`` needs to include
+the current source directory, while ``MathFunctions`` itself doesn't. This
+can be expressed with an ``INTERFACE`` usage requirement. Remember
+``INTERFACE`` means things that consumers require but the producer doesn't.
+
+At the end of ``MathFunctions/CMakeLists.txt``, use
+:command:`target_include_directories` with the ``INTERFACE`` keyword, as
+follows:
+
+.. raw:: html
+
+ <details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step4/MathFunctions/CMakeLists.txt
- :caption: MathFunctions/CMakeLists.txt
+ :caption: TODO 1: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-target_include_directories-INTERFACE
:language: cmake
:start-after: # to find MathFunctions.h
-Now that we've specified usage requirements for ``MathFunctions`` we can safely
-remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
+.. raw:: html
+
+ </details>
+
+Now that we've specified usage requirements for ``MathFunctions`` we can
+safely remove our uses of the ``EXTRA_INCLUDES`` variable from the top-level
``CMakeLists.txt``, here:
+.. raw:: html
+
+ <details><summary>TODO 2: Click to show/hide answer</summary>
+
.. literalinclude:: Step4/CMakeLists.txt
- :caption: CMakeLists.txt
+ :caption: TODO 2: CMakeLists.txt
:name: CMakeLists.txt-remove-EXTRA_INCLUDES
:language: cmake
:start-after: # add the MathFunctions library
:end-before: # add the executable
+.. raw:: html
+
+ </details>
+
And here:
+.. raw:: html
+
+ <details><summary>TODO 3: Click to show/hide answer</summary>
+
.. literalinclude:: Step4/CMakeLists.txt
- :caption: CMakeLists.txt
+ :caption: TODO 3: CMakeLists.txt
:name: CMakeLists.txt-target_include_directories-remove-EXTRA_INCLUDES
:language: cmake
:start-after: # so that we will find TutorialConfig.h
-Once this is done, run the :manual:`cmake <cmake(1)>` executable or the
-:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool or by using ``cmake --build .`` from the build
-directory.
+.. raw:: html
+
+ </details>
+
+Notice that with this technique, the only thing our executable target does to
+use our library is call :command:`target_link_libraries` with the name
+of the library target. In larger projects, the classic method of specifying
+library dependencies manually becomes very complicated very quickly.
diff --git a/Help/guide/tutorial/Adding a Custom Command and Generated File.rst b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
index 70c6695..343979e 100644
--- a/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
+++ b/Help/guide/tutorial/Adding a Custom Command and Generated File.rst
@@ -1,4 +1,4 @@
-Step 6: Adding a Custom Command and Generated File
+Step 8: Adding a Custom Command and Generated File
==================================================
Suppose, for the purpose of this tutorial, we decide that we never want to use
@@ -26,7 +26,7 @@ accomplish this.
First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for
``MakeTable`` is added as any other executable would be added.
-.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_executable-MakeTable
:language: cmake
@@ -36,7 +36,7 @@ First, at the top of ``MathFunctions/CMakeLists.txt``, the executable for
Then we add a custom command that specifies how to produce ``Table.h``
by running MakeTable.
-.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_custom_command-Table.h
:language: cmake
@@ -47,7 +47,7 @@ Next we have to let CMake know that ``mysqrt.cxx`` depends on the generated
file ``Table.h``. This is done by adding the generated ``Table.h`` to the list
of sources for the library MathFunctions.
-.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-Table.h
:language: cmake
@@ -57,7 +57,7 @@ of sources for the library MathFunctions.
We also have to add the current binary directory to the list of include
directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
-.. literalinclude:: Step7/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step9/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-target_include_directories-Table.h
:language: cmake
@@ -67,7 +67,7 @@ directories so that ``Table.h`` can be found and included by ``mysqrt.cxx``.
Now let's use the generated table. First, modify ``mysqrt.cxx`` to include
``Table.h``. Next, we can rewrite the ``mysqrt`` function to use the table:
-.. literalinclude:: Step7/MathFunctions/mysqrt.cxx
+.. literalinclude:: Step9/MathFunctions/mysqrt.cxx
:caption: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx
:language: c++
diff --git a/Help/guide/tutorial/Adding a Library.rst b/Help/guide/tutorial/Adding a Library.rst
index 71755be..46a8909 100644
--- a/Help/guide/tutorial/Adding a Library.rst
+++ b/Help/guide/tutorial/Adding a Library.rst
@@ -1,136 +1,458 @@
Step 2: Adding a Library
========================
-Now we will add a library to our project. This library will contain our own
+At this point, we have seen how to create a basic project using CMake. In this
+step, we will learn how to create and use a library in our project. We will
+also see how to make the use of our library optional.
+
+Exercise 1 - Creating a Library
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+To add a library in CMake, use the :command:`add_library` command and specify
+which source files should make up the library.
+
+Rather than placing all of the source files in one directory, we can organize
+our project with one or more subdirectories. In this case, we will create a
+subdirectory specifically for our library. Here, we can add a new
+``CMakeLists.txt`` file and one or more source files. In the top level
+``CMakeLists.txt`` file, we will use the :command:`add_subdirectory` command
+to add the subdirectory to the build.
+
+Once the library is created, it is connected to our executable target with
+:command:`target_include_directories` and :command:`target_link_libraries`.
+
+Goal
+----
+
+Add and use a library.
+
+Helpful Resources
+-----------------
+
+* :command:`add_library`
+* :command:`add_subdirectory`
+* :command:`target_include_directories`
+* :command:`target_link_libraries`
+* :variable:`PROJECT_SOURCE_DIR`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``tutorial.cxx``
+* ``MathFunctions/CMakeLists.txt``
+
+Getting Started
+---------------
+
+In this exercise, we will add a library to our project that contains our own
implementation for computing the square root of a number. The executable can
then use this library instead of the standard square root function provided by
the compiler.
-For this tutorial we will put the library into a subdirectory
-called ``MathFunctions``. This directory already contains a header file,
-``MathFunctions.h``, and a source file ``mysqrt.cxx``. The source file has one
-function called ``mysqrt`` that provides similar functionality to the
-compiler's ``sqrt`` function.
+For this tutorial we will put the library into a subdirectory called
+``MathFunctions``. This directory already contains a header file,
+``MathFunctions.h``, and a source file ``mysqrt.cxx``. We will not need to
+modify either of these files. The source file has one function called
+``mysqrt`` that provides similar functionality to the compiler's ``sqrt``
+function.
+
+From the ``Help/guide/tutorial/Step2`` directory, start with ``TODO 1`` and
+complete through ``TODO 6``.
+
+First, fill in the one line ``CMakeLists.txt`` in the ``MathFunctions``
+subdirectory.
+
+Next, edit the top level ``CMakeLists.txt``.
+
+Finally, use the newly created ``MathFunctions`` library in ``tutorial.cxx``
+
+Build and Run
+-------------
+
+Run the :manual:`cmake <cmake(1)>` executable or the
+:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
+with your chosen build tool.
+
+Below is a refresher of what that looks like from the command line:
+
+.. code-block:: console
+
+ mkdir Step2_build
+ cd Step2_build
+ cmake ../Step2
+ cmake --build .
+
+Try to use the newly built ``Tutorial`` and ensure that it is still
+producing accurate square root values.
+
+Solution
+--------
+
+In the ``CMakeLists.txt`` file in the ``MathFunctions`` directory, we create
+a library target called ``MathFunctions`` with :command:`add_library`. The
+source file for the library is passed as an argument to
+:command:`add_library`. This looks like the following line:
-Add the following one line ``CMakeLists.txt`` file to the ``MathFunctions``
-directory:
+.. raw:: html
+
+ <details><summary>TODO 1: Click to show/hide answer</summary>
.. literalinclude:: Step3/MathFunctions/CMakeLists.txt
- :caption: MathFunctions/CMakeLists.txt
- :name: MathFunctions/CMakeLists.txt
+ :caption: TODO 1: MathFunctions/CMakeLists.txt
+ :name: MathFunctions/CMakeLists.txt-add_library
:language: cmake
+ :end-before: # TODO 1
+
+.. raw:: html
+
+ </details>
To make use of the new library we will add an :command:`add_subdirectory`
call in the top-level ``CMakeLists.txt`` file so that the library will get
-built. We add the new library to the executable, and add ``MathFunctions`` as
-an include directory so that the ``MathFunctions.h`` header file can be found.
-The last few lines of the top-level ``CMakeLists.txt`` file should now look
-like:
+built.
+
+.. raw:: html
+
+ <details><summary>TODO 2: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+ :caption: TODO 2: CMakeLists.txt
+ :name: CMakeLists.txt-add_subdirectory
+
+ add_subdirectory(MathFunctions)
+
+.. raw:: html
+
+ </details>
+
+Next, the new library target is linked to the executable target using
+:command:`target_link_libraries`.
+
+.. raw:: html
+
+ <details><summary>TODO 3: Click to show/hide answer</summary>
+
+.. code-block:: cmake
+ :caption: TODO 3: CMakeLists.txt
+ :name: CMakeLists.txt-target_link_libraries
+
+ target_link_libraries(Tutorial PUBLIC MathFunctions)
+
+.. raw:: html
+
+ </details>
+
+Finally we need to specify the library's header file location. Modify
+:command:`target_include_directories` to add the ``MathFunctions`` subdirectory
+as an include directory so that the ``MathFunctions.h`` header file can be
+found.
+
+.. raw:: html
+
+ <details><summary>TODO 4: Click to show/hide answer</summary>
.. code-block:: cmake
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-add_subdirectory
+ :caption: TODO 4: CMakeLists.txt
+ :name: CMakeLists.txt-target_include_directories-step2
+
+ target_include_directories(Tutorial PUBLIC
+ "${PROJECT_BINARY_DIR}"
+ "${PROJECT_SOURCE_DIR}/MathFunctions"
+ )
+
+.. raw:: html
+
+ </details>
+
+Now let's use our library. In ``tutorial.cxx``, include ``MathFunctions.h``:
+
+.. raw:: html
+
+ <details><summary>TODO 5: Click to show/hide answer</summary>
- # add the MathFunctions library
- add_subdirectory(MathFunctions)
+.. code-block:: c++
+ :caption: TODO 5 : tutorial.cxx
+ :name: tutorial.cxx-include_MathFunctions.h
- # add the executable
- add_executable(Tutorial tutorial.cxx)
+ #include "MathFunctions.h"
- target_link_libraries(Tutorial PUBLIC MathFunctions)
+.. raw:: html
- # add the binary tree to the search path for include files
- # so that we will find TutorialConfig.h
- target_include_directories(Tutorial PUBLIC
- "${PROJECT_BINARY_DIR}"
- "${PROJECT_SOURCE_DIR}/MathFunctions"
- )
+ </details>
-Now let us make the ``MathFunctions`` library optional. While for the tutorial
+Lastly, replace ``sqrt`` with our library function ``mysqrt``.
+
+.. raw:: html
+
+ <details><summary>TODO 6: Click to show/hide answer</summary>
+
+.. code-block:: c++
+ :caption: TODO 6 : tutorial.cxx
+ :name: tutorial.cxx-call_mysqrt
+
+ const double outputValue = mysqrt(inputValue);
+
+.. raw:: html
+
+ </details>
+
+Exercise 2 - Making Our Library Optional
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Now let us make the MathFunctions library optional. While for the tutorial
there really isn't any need to do so, for larger projects this is a common
-occurrence. The first step is to add an option to the top-level
-``CMakeLists.txt`` file.
+occurrence.
+
+CMake can do this using the :command:`option` command. This gives users a
+variable which they can change when configuring their cmake build. This
+setting will be stored in the cache so that the user does not need to set
+the value each time they run CMake on a build directory.
+
+Goal
+----
+
+Add the option to build without ``MathFunctions``.
+
+
+Helpful Resources
+-----------------
+
+* :command:`if`
+* :command:`list`
+* :command:`option`
+* :command:`cmakedefine <configure_file>`
+
+Files to Edit
+-------------
+
+* ``CMakeLists.txt``
+* ``tutorial.cxx``
+* ``TutorialConfig.h.in``
+
+Getting Started
+---------------
+
+Start with the resulting files from Exercise 1. Complete ``TODO 7`` through
+``TODO 13``.
+
+First create a variable ``MY_MATH`` using the :command:`option` command
+in the top-level ``CMakeLists.txt`` file. In that same file, use that option
+to determine whether to build and use the ``MathFunctions`` library.
+
+Then, update ``tutorial.cxx`` and ``TutorialConfig.h.in`` to use ``MY_MATH``.
+
+Build and Run
+-------------
+
+Since we have our build directory already configured from Exercise 1, we can
+rebuild by simply calling the following:
+
+.. code-block:: console
+
+ cd ../Step2_build
+ cmake --build .
+
+Next, run the ``Tutorial`` executable on a few numbers to verify that it's
+still correct.
+
+Now let's update the value of ``USE_MYMATH`` to ``OFF``. The easiest way is to
+use the :manual:`cmake-gui <cmake-gui(1)>` or :manual:`ccmake <ccmake(1)>`
+if you're in the terminal. Or, alternatively, if you want to change the
+option from the command-line, try:
+
+.. code-block:: console
+
+ cmake ../Step2 -DUSE_MYMATH=OFF
+
+Now, rebuild the code with the following:
+
+.. code-block:: console
+
+ cmake --build .
+
+Then, run the executable again to ensure that it still works with
+``USE_MYMATH`` set to ``OFF``. Which function gives better results, ``sqrt``
+or ``mysqrt``?
+
+Solution
+--------
+
+The first step is to add an option to the top-level ``CMakeLists.txt`` file.
+This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
+:manual:`ccmake <ccmake(1)>` with a default value of ``ON`` that can be
+changed by the user.
+
+.. raw:: html
+
+ <details><summary>TODO 7: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt
- :caption: CMakeLists.txt
+ :caption: TODO 7: CMakeLists.txt
:name: CMakeLists.txt-option
:language: cmake
:start-after: # should we use our own math functions
- :end-before: # add the MathFunctions library
+ :end-before: # configure a header file to pass some of the CMake settings
-This option will be displayed in the :manual:`cmake-gui <cmake-gui(1)>` and
-:manual:`ccmake <ccmake(1)>`
-with a default value of ``ON`` that can be changed by the user. This setting
-will be stored in the cache so that the user does not need to set the value
-each time they run CMake on a build directory.
-
-The next change is to make building and linking the ``MathFunctions`` library
-conditional. To do this, we will create an ``if`` statement which checks the
-value of the option. Inside the ``if`` block, put the
-:command:`add_subdirectory` command from above with some additional list
-commands to store information needed to link to the library and add the
-subdirectory as an include directory in the ``Tutorial`` target.
-The end of the top-level ``CMakeLists.txt`` file will now look like the
-following:
+.. raw:: html
+
+ </details>
+
+Next, make building and linking the ``MathFunctions`` library
+conditional.
+
+Start by creating a :command:`list` of the optional library targets for our
+project. At the moment, it is just ``MathFunctions``. Let's name our list
+``EXTRA_LIBS``.
+
+Similarly, we need to make a :command:`list` for the optional includes which
+we will call ``EXTRA_INCLUDES``. In this list, we will ``APPEND`` the path of
+the header file needed for our library.
+
+Next, create an :command:`if` statement which checks the value of
+``USE_MYMATH``. Inside the :command:`if` block, put the
+:command:`add_subdirectory` command from Exercise 1 with the additional
+:command:`list` commands.
+
+When ``MY_MATH`` is ``ON``, the lists will be generated and will be added to
+our project. When ``MY_MATH`` is ``OFF``, the lists stay empty. With this
+strategy, we allow users to toggle ``MY_MATH`` to manipulate what library is
+used in the build.
+
+The top-level CMakeLists.txt file will now look like the following:
+
+.. raw:: html
+
+ <details><summary>TODO 8: Click to show/hide answer</summary>
.. literalinclude:: Step3/CMakeLists.txt
- :caption: CMakeLists.txt
- :name: CMakeLists.txt-target_link_libraries-EXTRA_LIBS
+ :caption: TODO 8: CMakeLists.txt
+ :name: CMakeLists.txt-USE_MYMATH
:language: cmake
:start-after: # add the MathFunctions library
+ :end-before: # add the executable
+
+.. raw:: html
+
+ </details>
-Note the use of the variable ``EXTRA_LIBS`` to collect up any optional
-libraries to later be linked into the executable. The variable
-``EXTRA_INCLUDES`` is used similarly for optional header files. This is a
-classic approach when dealing with many optional components, we will cover
-the modern approach in the next step.
+Now that we have these two lists, we need to update
+:command:`target_link_libraries` and :command:`target_include_directories` to
+use them. Changing them is fairly straightforward.
+
+For :command:`target_link_libraries`, we replace the written out
+library names with ``EXTRA_LIBS``. This looks like the following:
+
+.. raw:: html
+
+ <details><summary>TODO 9: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/CMakeLists.txt
+ :caption: TODO 9: CMakeLists.txt
+ :name: CMakeLists.txt-target_link_libraries-EXTRA_LIBS
+ :language: cmake
+ :start-after: add_executable(Tutorial tutorial.cxx)
+ :end-before: # TODO 3
+
+.. raw:: html
+
+ </details>
+
+Then, we do the same thing with :command:`target_include_directories` and
+``EXTRA_INCLUDES``.
+
+.. raw:: html
+
+ <details><summary>TODO 10: Click to show/hide answer</summary>
+
+.. literalinclude:: Step3/CMakeLists.txt
+ :caption: TODO 10 : CMakeLists.txt
+ :name: CMakeLists.txt-target_link_libraries-EXTRA_INCLUDES
+ :language: cmake
+ :start-after: # so that we will find TutorialConfig.h
+
+.. raw:: html
+
+ </details>
+
+Note that this is a classic approach when dealing with many components. We
+will cover the modern approach in the Step 3 of the tutorial.
The corresponding changes to the source code are fairly straightforward.
-First, in ``tutorial.cxx``, include the ``MathFunctions.h`` header if we
-need it:
+First, in ``tutorial.cxx``, we include the ``MathFunctions.h`` header if
+``MY_MATH`` is defined.
+
+.. raw:: html
+
+ <details><summary>TODO 11: Click to show/hide answer</summary>
.. literalinclude:: Step3/tutorial.cxx
- :caption: tutorial.cxx
+ :caption: TODO 11 : tutorial.cxx
:name: tutorial.cxx-ifdef-include
:language: c++
:start-after: // should we include the MathFunctions header
:end-before: int main
-Then, in the same file, make ``USE_MYMATH`` control which square root
+.. raw:: html
+
+ </details>
+
+Then, in the same file, we make ``USE_MYMATH`` control which square root
function is used:
+.. raw:: html
+
+ <details><summary>TODO 12: Click to show/hide answer</summary>
+
.. literalinclude:: Step3/tutorial.cxx
- :caption: tutorial.cxx
+ :caption: TODO 12 : tutorial.cxx
:name: tutorial.cxx-ifdef-const
:language: c++
:start-after: // which square root function should we use?
:end-before: std::cout << "The square root of
+.. raw:: html
+
+ </details>
+
Since the source code now requires ``USE_MYMATH`` we can add it to
``TutorialConfig.h.in`` with the following line:
+.. raw:: html
+
+ <details><summary>TODO 13: Click to show/hide answer</summary>
+
.. literalinclude:: Step3/TutorialConfig.h.in
- :caption: TutorialConfig.h.in
+ :caption: TODO 13 : TutorialConfig.h.in
:name: TutorialConfig.h.in-cmakedefine
:language: c++
:lines: 4
-**Exercise**: Why is it important that we configure ``TutorialConfig.h.in``
+.. raw:: html
+
+ </details>
+
+With these changes, our library is now completely optional to whoever is
+building and using it.
+
+Bonus Question
+--------------
+
+Why is it important that we configure ``TutorialConfig.h.in``
after the option for ``USE_MYMATH``? What would happen if we inverted the two?
-Run the :manual:`cmake <cmake(1)>` executable or the
-:manual:`cmake-gui <cmake-gui(1)>` to configure the project and then build it
-with your chosen build tool. Then run the built Tutorial executable.
+Answer
+------
-Now let's update the value of ``USE_MYMATH``. The easiest way is to use the
-:manual:`cmake-gui <cmake-gui(1)>` or :manual:`ccmake <ccmake(1)>` if you're
-in the terminal. Or, alternatively, if you want to change the option from the
-command-line, try:
+.. raw:: html
-.. code-block:: console
+ <details><summary>Click to show/hide answer</summary>
- cmake ../Step2 -DUSE_MYMATH=OFF
+We configure after because ``TutorialConfig.h.in`` uses the value of
+``USE_MYMATH``. If we configure the file before
+calling :command:`option`, we won't be using the expected value of
+``USE_MYMATH``.
-Rebuild and run the tutorial again.
+.. raw:: html
-Which function gives better results, ``sqrt`` or ``mysqrt``?
+ </details>
diff --git a/Help/guide/tutorial/Complete/CMakeLists.txt b/Help/guide/tutorial/Complete/CMakeLists.txt
index 41baf64..3cdaaae 100644
--- a/Help/guide/tutorial/Complete/CMakeLists.txt
+++ b/Help/guide/tutorial/Complete/CMakeLists.txt
@@ -41,7 +41,7 @@ add_subdirectory(MathFunctions)
add_executable(Tutorial tutorial.cxx)
set_target_properties(Tutorial PROPERTIES DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
-target_link_libraries(Tutorial PUBLIC MathFunctions)
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
@@ -84,6 +84,7 @@ do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")
+# setup installer
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
diff --git a/Help/guide/tutorial/Complete/License.txt b/Help/guide/tutorial/Complete/License.txt
index c62d00b..85760e5 100644
--- a/Help/guide/tutorial/Complete/License.txt
+++ b/Help/guide/tutorial/Complete/License.txt
@@ -1,2 +1,2 @@
This is the open source License.txt file introduced in
-CMake/Tutorial/Step7...
+CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Installing and Testing.rst b/Help/guide/tutorial/Installing and Testing.rst
index 394c986..8daf5aa 100644
--- a/Help/guide/tutorial/Installing and Testing.rst
+++ b/Help/guide/tutorial/Installing and Testing.rst
@@ -1,4 +1,4 @@
-Step 4: Installing and Testing
+Step 5: Installing and Testing
==============================
Now we can start adding install rules and testing support to our project.
@@ -12,7 +12,7 @@ executable and configured header.
So to the end of ``MathFunctions/CMakeLists.txt`` we add:
-.. literalinclude:: Step5/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step6/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-install-TARGETS
:language: cmake
@@ -20,7 +20,7 @@ So to the end of ``MathFunctions/CMakeLists.txt`` we add:
And to the end of the top-level ``CMakeLists.txt`` we add:
-.. literalinclude:: Step5/CMakeLists.txt
+.. literalinclude:: Step6/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-install-TARGETS
:language: cmake
@@ -65,7 +65,7 @@ Next let's test our application. At the end of the top-level ``CMakeLists.txt``
file we can enable testing and then add a number of basic tests to verify that
the application is working correctly.
-.. literalinclude:: Step5/CMakeLists.txt
+.. literalinclude:: Step6/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-enable_testing
:language: cmake
diff --git a/Help/guide/tutorial/Packaging Debug and Release.rst b/Help/guide/tutorial/Packaging Debug and Release.rst
index 91b46a7..fc2050e 100644
--- a/Help/guide/tutorial/Packaging Debug and Release.rst
+++ b/Help/guide/tutorial/Packaging Debug and Release.rst
@@ -10,8 +10,8 @@ possible, however, to setup CPack to bundle multiple build directories and
construct a package that contains multiple configurations of the same project.
First, we want to ensure that the debug and release builds use different names
-for the executables and libraries that will be installed. Let's use `d` as the
-postfix for the debug executable and libraries.
+for the libraries that will be installed. Let's use `d` as the
+postfix for the debug libraries.
Set :variable:`CMAKE_DEBUG_POSTFIX` near the beginning of the top-level
``CMakeLists.txt`` file:
@@ -44,7 +44,7 @@ Let's also add version numbering to the ``MathFunctions`` library. In
:end-before: # install rules
From the ``Step12`` directory, create ``debug`` and ``release``
-subbdirectories. The layout will look like:
+subdirectories. The layout will look like:
.. code-block:: none
diff --git a/Help/guide/tutorial/Packaging an Installer.rst b/Help/guide/tutorial/Packaging an Installer.rst
index 0ee5db2..11a1952 100644
--- a/Help/guide/tutorial/Packaging an Installer.rst
+++ b/Help/guide/tutorial/Packaging an Installer.rst
@@ -1,4 +1,4 @@
-Step 7: Packaging an Installer
+Step 9: Packaging an Installer
==============================
Next suppose that we want to distribute our project to other people so that
@@ -11,7 +11,7 @@ installations and package management features. To accomplish this we will use
CPack to create platform specific installers. Specifically we need to add a
few lines to the bottom of our top-level ``CMakeLists.txt`` file.
-.. literalinclude:: Step8/CMakeLists.txt
+.. literalinclude:: Step10/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-include-CPack
:language: cmake
@@ -38,15 +38,15 @@ binary directory run:
cpack
-To specify the generator, use the ``-G`` option. For multi-config builds, use
-``-C`` to specify the configuration. For example:
+To specify the generator, use the :option:`-G <cpack -G>` option. For multi-config builds,
+use :option:`-C <cpack -C>` to specify the configuration. For example:
.. code-block:: console
cpack -G ZIP -C Debug
For a list of available generators, see :manual:`cpack-generators(7)` or call
-``cpack --help``. An :cpack_gen:`archive generator <CPack Archive Generator>`
+:option:`cpack --help`. An :cpack_gen:`archive generator <CPack Archive Generator>`
like ZIP creates a compressed archive of all *installed* files.
To create an archive of the *full* source tree you would type:
diff --git a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
index 2d5f70e..1c49c23 100644
--- a/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
+++ b/Help/guide/tutorial/Selecting Static or Shared Libraries.rst
@@ -1,5 +1,5 @@
-Step 9: Selecting Static or Shared Libraries
-============================================
+Step 10: Selecting Static or Shared Libraries
+=============================================
In this section we will show how the :variable:`BUILD_SHARED_LIBS` variable can
be used to control the default behavior of :command:`add_library`,
@@ -19,7 +19,7 @@ library.
The first step is to update the starting section of the top-level
``CMakeLists.txt`` to look like:
-.. literalinclude:: Step10/CMakeLists.txt
+.. literalinclude:: Step11/CMakeLists.txt
:caption: CMakeLists.txt
:name: CMakeLists.txt-option-BUILD_SHARED_LIBS
:language: cmake
@@ -33,7 +33,7 @@ explicitly require that SqrtLibrary is built statically.
The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
-.. literalinclude:: Step10/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-add_library-STATIC
:language: cmake
@@ -42,7 +42,7 @@ The end result is that ``MathFunctions/CMakeLists.txt`` should look like:
Next, update ``MathFunctions/mysqrt.cxx`` to use the ``mathfunctions`` and
``detail`` namespaces:
-.. literalinclude:: Step10/MathFunctions/mysqrt.cxx
+.. literalinclude:: Step11/MathFunctions/mysqrt.cxx
:caption: MathFunctions/mysqrt.cxx
:name: MathFunctions/mysqrt.cxx-namespace
:language: c++
@@ -56,7 +56,7 @@ uses ``USE_MYMATH``:
Finally, update ``MathFunctions/MathFunctions.h`` to use dll export defines:
-.. literalinclude:: Step10/MathFunctions/MathFunctions.h
+.. literalinclude:: Step11/MathFunctions/MathFunctions.h
:caption: MathFunctions/MathFunctions.h
:name: MathFunctions/MathFunctions.h
:language: c++
@@ -67,7 +67,7 @@ library that has position independent code. The solution to this is to
explicitly set the :prop_tgt:`POSITION_INDEPENDENT_CODE` target property of
SqrtLibrary to be ``True`` no matter the build type.
-.. literalinclude:: Step10/MathFunctions/CMakeLists.txt
+.. literalinclude:: Step11/MathFunctions/CMakeLists.txt
:caption: MathFunctions/CMakeLists.txt
:name: MathFunctions/CMakeLists.txt-POSITION_INDEPENDENT_CODE
:language: cmake
diff --git a/Help/guide/tutorial/Step1/CMakeLists.txt b/Help/guide/tutorial/Step1/CMakeLists.txt
new file mode 100644
index 0000000..282951a
--- /dev/null
+++ b/Help/guide/tutorial/Step1/CMakeLists.txt
@@ -0,0 +1,16 @@
+# TODO 1: Set the minimum required version of CMake to be 3.10
+
+# TODO 2: Create a project named Tutorial
+
+# TODO 7: Set the project version number as 1.0 in the above project command
+
+# TODO 6: Set the variable CMAKE_CXX_STANDARD to 11
+# and the variable CMAKE_CXX_REQUIRED_STANDARD to True
+
+# TODO 8: Use configure_file to configure and copy TutorialConfig.h.in to
+# TutorialConfig.h
+
+# TODO 3: Add an executable called Tutorial to the project
+# Hint: Be sure to specify the source file as tutorial.cxx
+
+# TODO 9: Use target_include_directories to include ${PROJECT_BINARY_DIR}
diff --git a/Help/guide/tutorial/Step1/TutorialConfig.h.in b/Help/guide/tutorial/Step1/TutorialConfig.h.in
new file mode 100644
index 0000000..990bfbd
--- /dev/null
+++ b/Help/guide/tutorial/Step1/TutorialConfig.h.in
@@ -0,0 +1,2 @@
+// the configured options and settings for Tutorial
+// TODO 10: Define Tutorial_VERSION_MAJOR and Tutorial_VERSION_MINOR
diff --git a/Help/guide/tutorial/Step1/tutorial.cxx b/Help/guide/tutorial/Step1/tutorial.cxx
index 08323bf..64d0916 100644
--- a/Help/guide/tutorial/Step1/tutorial.cxx
+++ b/Help/guide/tutorial/Step1/tutorial.cxx
@@ -1,17 +1,22 @@
// A simple program that computes the square root of a number
#include <cmath>
-#include <cstdlib>
+#include <cstdlib> // TODO 5: Remove this line
#include <iostream>
#include <string>
+// TODO 11: Include TutorialConfig.h
+
int main(int argc, char* argv[])
{
if (argc < 2) {
+ // TODO 12: Create a print statement using Tutorial_VERSION_MAJOR
+ // and Tutorial_VERSION_MINOR
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
// convert input to double
+ // TODO 4: Replace atof(argv[1]) with std::stod(argv[1])
const double inputValue = atof(argv[1]);
// calculate square root
diff --git a/Help/guide/tutorial/Step10/CMakeLists.txt b/Help/guide/tutorial/Step10/CMakeLists.txt
index 55dc409..5c661aa 100644
--- a/Help/guide/tutorial/Step10/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/CMakeLists.txt
@@ -1,29 +1,37 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
-# control where the static and shared libraries are built so that on windows
-# we don't need to tinker with the path to run the executable
-set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
-set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+ "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
-option(BUILD_SHARED_LIBS "Build using shared libraries" ON)
+# should we use our own math functions
+option(USE_MYMATH "Use tutorial provided math implementation" ON)
-# configure a header file to pass the version number only
+# configure a header file to pass some of the CMake settings
+# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
# add the MathFunctions library
-add_subdirectory(MathFunctions)
+if(USE_MYMATH)
+ add_subdirectory(MathFunctions)
+ list(APPEND EXTRA_LIBS MathFunctions)
+endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC MathFunctions)
+target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
@@ -66,6 +74,7 @@ do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")
+# setup installer
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
diff --git a/Help/guide/tutorial/Step10/License.txt b/Help/guide/tutorial/Step10/License.txt
index c62d00b..85760e5 100644
--- a/Help/guide/tutorial/Step10/License.txt
+++ b/Help/guide/tutorial/Step10/License.txt
@@ -1,2 +1,2 @@
This is the open source License.txt file introduced in
-CMake/Tutorial/Step7...
+CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
index 0bfe20c..746f966 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step10/MathFunctions/CMakeLists.txt
@@ -1,55 +1,30 @@
-# add the library that runs
-add_library(MathFunctions MathFunctions.cxx)
+# first we add the executable that generates the table
+add_executable(MakeTable MakeTable.cxx)
+
+# add the command to generate the source code
+add_custom_command(
+ OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ DEPENDS MakeTable
+ )
+
+# add the main library
+add_library(MathFunctions
+ mysqrt.cxx
+ ${CMAKE_CURRENT_BINARY_DIR}/Table.h
+ )
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
+# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions
- INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- )
+ INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
+ PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
+ )
-# should we use our own math functions
-option(USE_MYMATH "Use tutorial provided math implementation" ON)
-if(USE_MYMATH)
-
- target_compile_definitions(MathFunctions PRIVATE "USE_MYMATH")
-
- # first we add the executable that generates the table
- add_executable(MakeTable MakeTable.cxx)
-
- # add the command to generate the source code
- add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- DEPENDS MakeTable
- )
-
- # library that just does sqrt
- add_library(SqrtLibrary STATIC
- mysqrt.cxx
- ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- )
-
- # state that we depend on our binary dir to find Table.h
- target_include_directories(SqrtLibrary PRIVATE
- ${CMAKE_CURRENT_BINARY_DIR}
- )
-
- # state that SqrtLibrary need PIC when the default is shared libraries
- set_target_properties(SqrtLibrary PROPERTIES
- POSITION_INDEPENDENT_CODE ${BUILD_SHARED_LIBS}
- )
-
- target_link_libraries(MathFunctions PRIVATE SqrtLibrary)
-endif()
-
-# define the symbol stating we are using the declspec(dllexport) when
-# building on windows
-target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
+target_link_libraries(MathFunctions tutorial_compiler_flags)
# install rules
-set(installable_libs MathFunctions)
-if(TARGET SqrtLibrary)
- list(APPEND installable_libs SqrtLibrary)
-endif()
+set(installable_libs MathFunctions tutorial_compiler_flags)
install(TARGETS ${installable_libs} DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
index 3fb547b..cd36bcc 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
+++ b/Help/guide/tutorial/Step10/MathFunctions/MathFunctions.h
@@ -1,14 +1 @@
-
-#if defined(_WIN32)
-# if defined(EXPORTING_MYMATH)
-# define DECLSPEC __declspec(dllexport)
-# else
-# define DECLSPEC __declspec(dllimport)
-# endif
-#else // non windows
-# define DECLSPEC
-#endif
-
-namespace mathfunctions {
-double DECLSPEC sqrt(double x);
-}
+double mysqrt(double x);
diff --git a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
index 8153f18..7d80ee9 100644
--- a/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step10/MathFunctions/mysqrt.cxx
@@ -5,8 +5,6 @@
// include the generated table
#include "Table.h"
-namespace mathfunctions {
-namespace detail {
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -33,5 +31,3 @@ double mysqrt(double x)
return result;
}
-}
-}
diff --git a/Help/guide/tutorial/Step10/TutorialConfig.h.in b/Help/guide/tutorial/Step10/TutorialConfig.h.in
index 7e4d7fa..e23f521 100644
--- a/Help/guide/tutorial/Step10/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step10/TutorialConfig.h.in
@@ -1,3 +1,4 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+#cmakedefine USE_MYMATH
diff --git a/Help/guide/tutorial/Step10/tutorial.cxx b/Help/guide/tutorial/Step10/tutorial.cxx
index 37a0333..b3c6a4f 100644
--- a/Help/guide/tutorial/Step10/tutorial.cxx
+++ b/Help/guide/tutorial/Step10/tutorial.cxx
@@ -1,11 +1,15 @@
// A simple program that computes the square root of a number
+#include <cmath>
#include <iostream>
-#include <sstream>
#include <string>
-#include "MathFunctions.h"
#include "TutorialConfig.h"
+// should we include the MathFunctions header?
+#ifdef USE_MYMATH
+# include "MathFunctions.h"
+#endif
+
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -19,7 +23,12 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
- const double outputValue = mathfunctions::sqrt(inputValue);
+ // which square root function should we use?
+#ifdef USE_MYMATH
+ const double outputValue = mysqrt(inputValue);
+#else
+ const double outputValue = sqrt(inputValue);
+#endif
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
diff --git a/Help/guide/tutorial/Step11/CMakeLists.txt b/Help/guide/tutorial/Step11/CMakeLists.txt
index 1044748..046bfc9 100644
--- a/Help/guide/tutorial/Step11/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/CMakeLists.txt
@@ -3,6 +3,7 @@ cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
+# specify the C++ standard
add_library(tutorial_compiler_flags INTERFACE)
target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
@@ -31,7 +32,7 @@ add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC MathFunctions)
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
@@ -46,7 +47,7 @@ install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
# enable testing
-enable_testing()
+include(CTest)
# does the application run
add_test(NAME Runs COMMAND Tutorial 25)
@@ -74,6 +75,7 @@ do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")
+# setup installer
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
diff --git a/Help/guide/tutorial/Step11/License.txt b/Help/guide/tutorial/Step11/License.txt
index c62d00b..85760e5 100644
--- a/Help/guide/tutorial/Step11/License.txt
+++ b/Help/guide/tutorial/Step11/License.txt
@@ -1,2 +1,2 @@
This is the open source License.txt file introduced in
-CMake/Tutorial/Step7...
+CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
index 0d287ca..0e86a12 100644
--- a/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step11/MathFunctions/CMakeLists.txt
@@ -47,7 +47,7 @@ endif()
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# define the symbol stating we are using the declspec(dllexport) when
-#building on windows
+# building on windows
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
# install rules
diff --git a/Help/guide/tutorial/Step11/tutorial.cxx b/Help/guide/tutorial/Step11/tutorial.cxx
index a4f44d5..37a0333 100644
--- a/Help/guide/tutorial/Step11/tutorial.cxx
+++ b/Help/guide/tutorial/Step11/tutorial.cxx
@@ -1,5 +1,6 @@
// A simple program that computes the square root of a number
#include <iostream>
+#include <sstream>
#include <string>
#include "MathFunctions.h"
diff --git a/Help/guide/tutorial/Step12/CMakeLists.txt b/Help/guide/tutorial/Step12/CMakeLists.txt
index 63f9643..220ed4b 100644
--- a/Help/guide/tutorial/Step12/CMakeLists.txt
+++ b/Help/guide/tutorial/Step12/CMakeLists.txt
@@ -37,7 +37,7 @@ add_subdirectory(MathFunctions)
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC MathFunctions)
+target_link_libraries(Tutorial PUBLIC MathFunctions tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
@@ -80,6 +80,7 @@ do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")
+# setup installer
include(InstallRequiredSystemLibraries)
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
diff --git a/Help/guide/tutorial/Step12/License.txt b/Help/guide/tutorial/Step12/License.txt
index c62d00b..85760e5 100644
--- a/Help/guide/tutorial/Step12/License.txt
+++ b/Help/guide/tutorial/Step12/License.txt
@@ -1,2 +1,2 @@
This is the open source License.txt file introduced in
-CMake/Tutorial/Step7...
+CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Step2/CMakeLists.txt b/Help/guide/tutorial/Step2/CMakeLists.txt
index 7aa59e9..2f7d56e 100644
--- a/Help/guide/tutorial/Step2/CMakeLists.txt
+++ b/Help/guide/tutorial/Step2/CMakeLists.txt
@@ -7,13 +7,36 @@ project(Tutorial VERSION 1.0)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
+# TODO 7: Create a variable MY_MATH using option and set default to ON
+
# configure a header file to pass some of the CMake settings
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
+# TODO 8: Use list() and APPEND to create a list of optional libraries
+# called EXTRA_LIBS and a list of optional include directories called
+# EXTRA_INCLUDES. Add the MathFunctions library and source directory to
+# the appropriate lists.
+#
+# Only call add_subdirectory and only add MathFunctions specific values
+# to EXTRA_LIBS and EXTRA_INCLUDES if USE_MYMATH is true.
+
+# TODO 2: Use add_subdirectory() to add MathFunctions to this project
+
# add the executable
add_executable(Tutorial tutorial.cxx)
+# TODO 9: Use EXTRA_LIBS instead of the MathFunctions specific values
+# in target_link_libraries.
+
+# TODO 3: Use target_link_libraries to link the library to our executable
+
+# TODO 4: Add MathFunctions to Tutorial's target_include_directories()
+# Hint: ${PROJECT_SOURCE_DIR} is a path to the project source. AKA This folder!
+
+# TODO 10: Use EXTRA_INCLUDES instead of the MathFunctions specific values
+# in target_include_directories.
+
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
diff --git a/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
new file mode 100644
index 0000000..b7779b7
--- /dev/null
+++ b/Help/guide/tutorial/Step2/MathFunctions/CMakeLists.txt
@@ -0,0 +1,2 @@
+# TODO 1: Add a library called MathFunctions
+# Hint: You will need the add_library command
diff --git a/Help/guide/tutorial/Step2/TutorialConfig.h.in b/Help/guide/tutorial/Step2/TutorialConfig.h.in
index 7e4d7fa..adb4c55 100644
--- a/Help/guide/tutorial/Step2/TutorialConfig.h.in
+++ b/Help/guide/tutorial/Step2/TutorialConfig.h.in
@@ -1,3 +1,5 @@
// the configured options and settings for Tutorial
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
+
+// TODO 13: use cmakedefine to define MY_MATH
diff --git a/Help/guide/tutorial/Step2/tutorial.cxx b/Help/guide/tutorial/Step2/tutorial.cxx
index 53b0810..f83aa7e 100644
--- a/Help/guide/tutorial/Step2/tutorial.cxx
+++ b/Help/guide/tutorial/Step2/tutorial.cxx
@@ -5,6 +5,10 @@
#include "TutorialConfig.h"
+// TODO 11: Only include MathFunctions if MY_MATH is defined
+
+// TODO 5: Include MathFunctions.h
+
int main(int argc, char* argv[])
{
if (argc < 2) {
@@ -18,6 +22,10 @@ int main(int argc, char* argv[])
// convert input to double
const double inputValue = std::stod(argv[1]);
+ // TODO 12: Use mysqrt if MY_MATH is defined and sqrt otherwise
+
+ // TODO 6: Replace sqrt with mysqrt
+
// calculate square root
const double outputValue = sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
diff --git a/Help/guide/tutorial/Step3/CMakeLists.txt b/Help/guide/tutorial/Step3/CMakeLists.txt
index 1c12816..007770a 100644
--- a/Help/guide/tutorial/Step3/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/CMakeLists.txt
@@ -14,6 +14,8 @@ option(USE_MYMATH "Use tutorial provided math implementation" ON)
# to the source code
configure_file(TutorialConfig.h.in TutorialConfig.h)
+# TODO 2: Remove EXTRA_INCLUDES list
+
# add the MathFunctions library
if(USE_MYMATH)
add_subdirectory(MathFunctions)
@@ -26,6 +28,8 @@ add_executable(Tutorial tutorial.cxx)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+# TODO 3: Remove use of EXTRA_INCLUDES
+
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
diff --git a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
index 8b443a6..7bf05e0 100644
--- a/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step3/MathFunctions/CMakeLists.txt
@@ -1 +1,5 @@
add_library(MathFunctions mysqrt.cxx)
+
+# TODO 1: State that anybody linking to MathFunctions needs to include the
+# current source directory, while MathFunctions itself doesn't.
+# Hint: Use target_include_directories with the INTERFACE keyword
diff --git a/Help/guide/tutorial/Step5/CMakeLists.txt b/Help/guide/tutorial/Step5/CMakeLists.txt
index 82d00c8..4003c21 100644
--- a/Help/guide/tutorial/Step5/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/CMakeLists.txt
@@ -1,11 +1,20 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+ "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
@@ -22,45 +31,10 @@ endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
)
-
-# add the install targets
-install(TARGETS Tutorial DESTINATION bin)
-install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
- DESTINATION include
- )
-
-# enable testing
-enable_testing()
-
-# does the application run
-add_test(NAME Runs COMMAND Tutorial 25)
-
-# does the usage message work?
-add_test(NAME Usage COMMAND Tutorial)
-set_tests_properties(Usage
- PROPERTIES PASS_REGULAR_EXPRESSION "Usage:.*number"
- )
-
-# define a function to simplify adding tests
-function(do_test target arg result)
- add_test(NAME Comp${arg} COMMAND ${target} ${arg})
- set_tests_properties(Comp${arg}
- PROPERTIES PASS_REGULAR_EXPRESSION ${result}
- )
-endfunction()
-
-# do a bunch of result based tests
-do_test(Tutorial 4 "4 is 2")
-do_test(Tutorial 9 "9 is 3")
-do_test(Tutorial 5 "5 is 2.236")
-do_test(Tutorial 7 "7 is 2.645")
-do_test(Tutorial 25 "25 is 5")
-do_test(Tutorial -25 "-25 is (-nan|nan|0)")
-do_test(Tutorial 0.0001 "0.0001 is 0.01")
diff --git a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
index b12f27d..e02f211 100644
--- a/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step5/MathFunctions/CMakeLists.txt
@@ -6,6 +6,4 @@ target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
-# install rules
-install(TARGETS MathFunctions DESTINATION lib)
-install(FILES MathFunctions.h DESTINATION include)
+target_link_libraries(MathFunctions tutorial_compiler_flags)
diff --git a/Help/guide/tutorial/Step6/CMakeLists.txt b/Help/guide/tutorial/Step6/CMakeLists.txt
index 82d00c8..da9e852 100644
--- a/Help/guide/tutorial/Step6/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/CMakeLists.txt
@@ -1,11 +1,20 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+ "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
@@ -22,7 +31,7 @@ endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
diff --git a/Help/guide/tutorial/Step6/CTestConfig.cmake b/Help/guide/tutorial/Step6/CTestConfig.cmake
new file mode 100644
index 0000000..73efdb1
--- /dev/null
+++ b/Help/guide/tutorial/Step6/CTestConfig.cmake
@@ -0,0 +1,7 @@
+set(CTEST_PROJECT_NAME "CMakeTutorial")
+set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
+
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "my.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
index 42e098a..226099a 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step6/MathFunctions/CMakeLists.txt
@@ -6,29 +6,9 @@ target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
-# does this system provide the log and exp functions?
-include(CheckCXXSourceCompiles)
-check_cxx_source_compiles("
- #include <cmath>
- int main() {
- std::log(1.0);
- return 0;
- }
-" HAVE_LOG)
-check_cxx_source_compiles("
- #include <cmath>
- int main() {
- std::exp(1.0);
- return 0;
- }
-" HAVE_EXP)
-
-# add compile definitions
-if(HAVE_LOG AND HAVE_EXP)
- target_compile_definitions(MathFunctions
- PRIVATE "HAVE_LOG" "HAVE_EXP")
-endif()
+target_link_libraries(MathFunctions tutorial_compiler_flags)
# install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions tutorial_compiler_flags)
+install(TARGETS ${installable_libs} DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step6/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step6/MathFunctions/MakeTable.cxx
deleted file mode 100644
index ee58556..0000000
--- a/Help/guide/tutorial/Step6/MathFunctions/MakeTable.cxx
+++ /dev/null
@@ -1,25 +0,0 @@
-// A simple program that builds a sqrt table
-#include <cmath>
-#include <fstream>
-#include <iostream>
-
-int main(int argc, char* argv[])
-{
- // make sure we have enough arguments
- if (argc < 2) {
- return 1;
- }
-
- std::ofstream fout(argv[1], std::ios_base::out);
- const bool fileOpen = fout.is_open();
- if (fileOpen) {
- fout << "double sqrtTable[] = {" << std::endl;
- for (int i = 0; i < 10; ++i) {
- fout << sqrt(static_cast<double>(i)) << "," << std::endl;
- }
- // close the table with a zero
- fout << "0};" << std::endl;
- fout.close();
- }
- return fileOpen ? 0 : 1; // return 0 if wrote the file
-}
diff --git a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
index 7eecd26..abe767d 100644
--- a/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step6/MathFunctions/mysqrt.cxx
@@ -1,4 +1,3 @@
-#include <cmath>
#include <iostream>
#include "MathFunctions.h"
@@ -10,12 +9,6 @@ double mysqrt(double x)
return 0;
}
- // if we have both log and exp then use them
-#if defined(HAVE_LOG) && defined(HAVE_EXP)
- double result = std::exp(std::log(x) * 0.5);
- std::cout << "Computing sqrt of " << x << " to be " << result
- << " using log and exp" << std::endl;
-#else
double result = x;
// do ten iterations
@@ -27,6 +20,5 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
-#endif
return result;
}
diff --git a/Help/guide/tutorial/Step7/CMakeLists.txt b/Help/guide/tutorial/Step7/CMakeLists.txt
index 82d00c8..d26a90c 100644
--- a/Help/guide/tutorial/Step7/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/CMakeLists.txt
@@ -1,11 +1,20 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+ "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
@@ -22,7 +31,7 @@ endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
@@ -37,7 +46,7 @@ install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
# enable testing
-enable_testing()
+include(CTest)
# does the application run
add_test(NAME Runs COMMAND Tutorial 25)
diff --git a/Help/guide/tutorial/Step7/CTestConfig.cmake b/Help/guide/tutorial/Step7/CTestConfig.cmake
new file mode 100644
index 0000000..73efdb1
--- /dev/null
+++ b/Help/guide/tutorial/Step7/CTestConfig.cmake
@@ -0,0 +1,7 @@
+set(CTEST_PROJECT_NAME "CMakeTutorial")
+set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")
+
+set(CTEST_DROP_METHOD "http")
+set(CTEST_DROP_SITE "my.cdash.org")
+set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial")
+set(CTEST_DROP_SITE_CDASH TRUE)
diff --git a/Help/guide/tutorial/Step7/License.txt b/Help/guide/tutorial/Step7/License.txt
deleted file mode 100644
index c62d00b..0000000
--- a/Help/guide/tutorial/Step7/License.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is the open source License.txt file introduced in
-CMake/Tutorial/Step7...
diff --git a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
index 9ede4b3..226099a 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step7/MathFunctions/CMakeLists.txt
@@ -1,29 +1,14 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-
-# add the command to generate the source code
-add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- DEPENDS MakeTable
- )
-
-# add the main library
-add_library(MathFunctions
- mysqrt.cxx
- ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- )
+add_library(MathFunctions mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
-# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the
-# TutorialConfig.h include is an implementation detail
-# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
+target_link_libraries(MathFunctions tutorial_compiler_flags)
+
# install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions tutorial_compiler_flags)
+install(TARGETS ${installable_libs} DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step7/MathFunctions/MakeTable.cxx b/Help/guide/tutorial/Step7/MathFunctions/MakeTable.cxx
deleted file mode 100644
index ee58556..0000000
--- a/Help/guide/tutorial/Step7/MathFunctions/MakeTable.cxx
+++ /dev/null
@@ -1,25 +0,0 @@
-// A simple program that builds a sqrt table
-#include <cmath>
-#include <fstream>
-#include <iostream>
-
-int main(int argc, char* argv[])
-{
- // make sure we have enough arguments
- if (argc < 2) {
- return 1;
- }
-
- std::ofstream fout(argv[1], std::ios_base::out);
- const bool fileOpen = fout.is_open();
- if (fileOpen) {
- fout << "double sqrtTable[] = {" << std::endl;
- for (int i = 0; i < 10; ++i) {
- fout << sqrt(static_cast<double>(i)) << "," << std::endl;
- }
- // close the table with a zero
- fout << "0};" << std::endl;
- fout.close();
- }
- return fileOpen ? 0 : 1; // return 0 if wrote the file
-}
diff --git a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
index 7d80ee9..abe767d 100644
--- a/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step7/MathFunctions/mysqrt.cxx
@@ -2,9 +2,6 @@
#include "MathFunctions.h"
-// include the generated table
-#include "Table.h"
-
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -12,12 +9,7 @@ double mysqrt(double x)
return 0;
}
- // use the table to help find an initial value
double result = x;
- if (x >= 1 && x < 10) {
- std::cout << "Use the table to help find an initial value " << std::endl;
- result = sqrtTable[static_cast<int>(x)];
- }
// do ten iterations
for (int i = 0; i < 10; ++i) {
@@ -28,6 +20,5 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
-
return result;
}
diff --git a/Help/guide/tutorial/Step8/CMakeLists.txt b/Help/guide/tutorial/Step8/CMakeLists.txt
index 4c78b94..cb87281 100644
--- a/Help/guide/tutorial/Step8/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/CMakeLists.txt
@@ -1,11 +1,21 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+ "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
+
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
@@ -22,7 +32,7 @@ endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
@@ -37,7 +47,7 @@ install(FILES "${PROJECT_BINARY_DIR}/TutorialConfig.h"
)
# enable testing
-enable_testing()
+include(CTest)
# does the application run
add_test(NAME Runs COMMAND Tutorial 25)
@@ -64,11 +74,3 @@ do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")
-
-# setup installer
-include(InstallRequiredSystemLibraries)
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
-set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
-set(CPACK_SOURCE_GENERATOR "TGZ")
-include(CPack)
diff --git a/Help/guide/tutorial/Step8/License.txt b/Help/guide/tutorial/Step8/License.txt
deleted file mode 100644
index c62d00b..0000000
--- a/Help/guide/tutorial/Step8/License.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is the open source License.txt file introduced in
-CMake/Tutorial/Step7...
diff --git a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
index 9ede4b3..a832003 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step8/MathFunctions/CMakeLists.txt
@@ -1,29 +1,37 @@
-# first we add the executable that generates the table
-add_executable(MakeTable MakeTable.cxx)
-
-# add the command to generate the source code
-add_custom_command(
- OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- COMMAND MakeTable ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- DEPENDS MakeTable
- )
-
-# add the main library
-add_library(MathFunctions
- mysqrt.cxx
- ${CMAKE_CURRENT_BINARY_DIR}/Table.h
- )
+add_library(MathFunctions mysqrt.cxx)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
-# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the
-# TutorialConfig.h include is an implementation detail
-# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
- PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
+target_link_libraries(MathFunctions tutorial_compiler_flags)
+
+# does this system provide the log and exp functions?
+include(CheckCXXSourceCompiles)
+check_cxx_source_compiles("
+ #include <cmath>
+ int main() {
+ std::log(1.0);
+ return 0;
+ }
+" HAVE_LOG)
+check_cxx_source_compiles("
+ #include <cmath>
+ int main() {
+ std::exp(1.0);
+ return 0;
+ }
+" HAVE_EXP)
+
+# add compile definitions
+if(HAVE_LOG AND HAVE_EXP)
+ target_compile_definitions(MathFunctions
+ PRIVATE "HAVE_LOG" "HAVE_EXP")
+endif()
+
# install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions tutorial_compiler_flags)
+install(TARGETS ${installable_libs} DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
index 7d80ee9..7eecd26 100644
--- a/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
+++ b/Help/guide/tutorial/Step8/MathFunctions/mysqrt.cxx
@@ -1,10 +1,8 @@
+#include <cmath>
#include <iostream>
#include "MathFunctions.h"
-// include the generated table
-#include "Table.h"
-
// a hack square root calculation using simple operations
double mysqrt(double x)
{
@@ -12,12 +10,13 @@ double mysqrt(double x)
return 0;
}
- // use the table to help find an initial value
+ // if we have both log and exp then use them
+#if defined(HAVE_LOG) && defined(HAVE_EXP)
+ double result = std::exp(std::log(x) * 0.5);
+ std::cout << "Computing sqrt of " << x << " to be " << result
+ << " using log and exp" << std::endl;
+#else
double result = x;
- if (x >= 1 && x < 10) {
- std::cout << "Use the table to help find an initial value " << std::endl;
- result = sqrtTable[static_cast<int>(x)];
- }
// do ten iterations
for (int i = 0; i < 10; ++i) {
@@ -28,6 +27,6 @@ double mysqrt(double x)
result = result + 0.5 * delta / result;
std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
}
-
+#endif
return result;
}
diff --git a/Help/guide/tutorial/Step9/CMakeLists.txt b/Help/guide/tutorial/Step9/CMakeLists.txt
index 6bae26e..d26a90c 100644
--- a/Help/guide/tutorial/Step9/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/CMakeLists.txt
@@ -1,11 +1,20 @@
-cmake_minimum_required(VERSION 3.10)
+cmake_minimum_required(VERSION 3.15)
# set the project name and version
project(Tutorial VERSION 1.0)
# specify the C++ standard
-set(CMAKE_CXX_STANDARD 11)
-set(CMAKE_CXX_STANDARD_REQUIRED True)
+add_library(tutorial_compiler_flags INTERFACE)
+target_compile_features(tutorial_compiler_flags INTERFACE cxx_std_11)
+
+# add compiler warning flags just when building this project via
+# the BUILD_INTERFACE genex
+set(gcc_like_cxx "$<COMPILE_LANG_AND_ID:CXX,ARMClang,AppleClang,Clang,GNU,LCC>")
+set(msvc_cxx "$<COMPILE_LANG_AND_ID:CXX,MSVC>")
+target_compile_options(tutorial_compiler_flags INTERFACE
+ "$<${gcc_like_cxx}:$<BUILD_INTERFACE:-Wall;-Wextra;-Wshadow;-Wformat=2;-Wunused>>"
+ "$<${msvc_cxx}:$<BUILD_INTERFACE:-W3>>"
+)
# should we use our own math functions
option(USE_MYMATH "Use tutorial provided math implementation" ON)
@@ -22,7 +31,7 @@ endif()
# add the executable
add_executable(Tutorial tutorial.cxx)
-target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
+target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS} tutorial_compiler_flags)
# add the binary tree to the search path for include files
# so that we will find TutorialConfig.h
@@ -64,10 +73,3 @@ do_test(Tutorial 7 "7 is 2.645")
do_test(Tutorial 25 "25 is 5")
do_test(Tutorial -25 "-25 is (-nan|nan|0)")
do_test(Tutorial 0.0001 "0.0001 is 0.01")
-
-include(InstallRequiredSystemLibraries)
-set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")
-set(CPACK_PACKAGE_VERSION_MAJOR "${Tutorial_VERSION_MAJOR}")
-set(CPACK_PACKAGE_VERSION_MINOR "${Tutorial_VERSION_MINOR}")
-set(CPACK_SOURCE_GENERATOR "TGZ")
-include(CPack)
diff --git a/Help/guide/tutorial/Step9/License.txt b/Help/guide/tutorial/Step9/License.txt
index c62d00b..85760e5 100644
--- a/Help/guide/tutorial/Step9/License.txt
+++ b/Help/guide/tutorial/Step9/License.txt
@@ -1,2 +1,2 @@
This is the open source License.txt file introduced in
-CMake/Tutorial/Step7...
+CMake/Tutorial/Step9...
diff --git a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
index 50f0701..8a08157 100644
--- a/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
+++ b/Help/guide/tutorial/Step9/MathFunctions/CMakeLists.txt
@@ -16,12 +16,17 @@ add_library(MathFunctions
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
+# state that we depend on Tutorial_BINARY_DIR but consumers don't, as the
+# TutorialConfig.h include is an implementation detail
# state that we depend on our binary dir to find Table.h
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
PRIVATE ${CMAKE_CURRENT_BINARY_DIR}
)
+target_link_libraries(MathFunctions tutorial_compiler_flags)
+
# install rules
-install(TARGETS MathFunctions DESTINATION lib)
+set(installable_libs MathFunctions tutorial_compiler_flags)
+install(TARGETS ${installable_libs} DESTINATION lib)
install(FILES MathFunctions.h DESTINATION include)
diff --git a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx b/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
deleted file mode 100644
index 0145300..0000000
--- a/Help/guide/tutorial/Step9/MathFunctions/MathFunctions.cxx
+++ /dev/null
@@ -1,19 +0,0 @@
-
-#include "MathFunctions.h"
-
-#include <cmath>
-
-#ifdef USE_MYMATH
-# include "mysqrt.h"
-#endif
-
-namespace mathfunctions {
-double sqrt(double x)
-{
-#ifdef USE_MYMATH
- return detail::mysqrt(x);
-#else
- return std::sqrt(x);
-#endif
-}
-}
diff --git a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h b/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h
deleted file mode 100644
index e1c42ef..0000000
--- a/Help/guide/tutorial/Step9/MathFunctions/mysqrt.h
+++ /dev/null
@@ -1,6 +0,0 @@
-
-namespace mathfunctions {
-namespace detail {
-double mysqrt(double x);
-}
-}
diff --git a/Help/guide/tutorial/index.rst b/Help/guide/tutorial/index.rst
index 09553cb..1ab0009 100644
--- a/Help/guide/tutorial/index.rst
+++ b/Help/guide/tutorial/index.rst
@@ -24,13 +24,13 @@ provides the complete solution for the previous step.
A Basic Starting Point
Adding a Library
Adding Usage Requirements for a Library
+ Adding Generator Expressions
Installing and Testing
+ Adding Support for a Testing Dashboard
Adding System Introspection
Adding a Custom Command and Generated File
Packaging an Installer
- Adding Support for a Testing Dashboard
Selecting Static or Shared Libraries
- Adding Generator Expressions
Adding Export Configuration
Packaging Debug and Release
diff --git a/Help/guide/user-interaction/index.rst b/Help/guide/user-interaction/index.rst
index ba8196b..9cc5816 100644
--- a/Help/guide/user-interaction/index.rst
+++ b/Help/guide/user-interaction/index.rst
@@ -71,8 +71,8 @@ The CMake tooling may report warnings which are intended
for the provider of the software, not intended for the
consumer of the software. Such warnings end with "This
warning is for project developers". Users may disable
-such warnings by passing the ``-Wno-dev`` flag to
-:manual:`cmake(1)`.
+such warnings by passing the :option:`-Wno-dev <cmake -Wno-dev>`
+flag to :manual:`cmake(1)`.
cmake-gui tool
--------------
@@ -153,13 +153,13 @@ platform. Usually, the default generator is sufficient
to allow the user to proceed to build the software.
The user may override the default generator with
-the ``-G`` option:
+the :option:`-G <cmake -G>` option:
.. code-block:: console
$ cmake .. -G Ninja
-The output of ``cmake --help`` includes a list of
+The output of :option:`cmake --help` includes a list of
:manual:`generators <cmake-generators(7)>` available
for the user to choose from. Note that generator
names are case sensitive.
@@ -196,7 +196,8 @@ VisualC++ compiler, or a combination of the two:
$ cmake .. -G "Visual Studio 16 2019"
Visual Studio generators can target different architectures.
-One can specify the target architecture using the `-A` option:
+One can specify the target architecture using the
+:option:`-A <cmake -A>` option:
.. code-block:: console
@@ -214,8 +215,8 @@ generator to use, typically a choice between a ``Makefile``
or a ``Ninja`` based generator.
Note that it is not possible to change the generator
-with ``-G`` after the first invocation of CMake. To
-change the generator, the build directory must be
+with :option:`-G <cmake -G>` after the first invocation of CMake.
+To change the generator, the build directory must be
deleted and the build must be started from scratch.
When generating Visual Studio project and solutions
@@ -223,7 +224,7 @@ files several other options are available to use when
initially running :manual:`cmake(1)`.
The Visual Studio toolset can be specified with the
-``-T`` option:
+:option:`cmake -T` option:
.. code-block:: console
@@ -232,9 +233,9 @@ The Visual Studio toolset can be specified with the
$ # Build targeting Windows XP
$ cmake.exe .. -G "Visual Studio 16 2019" -A x64 -T v120_xp
-Whereas the ``-A`` option specifies the _target_
-architecture, the ``-T`` option can be used to specify
-details of the toolchain used. For example, `-Thost=x64`
+Whereas the :option:`-A <cmake -A>` option specifies the _target_
+architecture, the :option:`-T <cmake -T>` option can be used to specify
+details of the toolchain used. For example, ``-Thost=x64``
can be given to select the 64-bit version of the host
tools. The following demonstrates how to use 64-bit
tools and also build for a 64-bit target architecture:
@@ -337,7 +338,7 @@ or later on a subsequent invocation of
$ cd build
$ cmake . -DCMAKE_BUILD_TYPE=Debug
-The ``-U`` flag may be used to unset variables
+The :option:`-U <cmake -U>` flag may be used to unset variables
on the :manual:`cmake(1)` command line:
.. code-block:: console
@@ -351,7 +352,7 @@ on the command line can be modified using the
The :manual:`cmake(1)` tool allows specifying a
file to use to populate the initial cache using
-the ``-C`` option. This can be useful to simplify
+the :option:`-C <cmake -C>` option. This can be useful to simplify
commands and scripts which repeatedly require the
same cache entries.
@@ -427,10 +428,10 @@ Using presets on the command-line
---------------------------------
When using the :manual:`cmake(1)` command line tool, a
-preset can be invoked by using the ``--preset`` option. If
-``--preset`` is specified, the generator and build
-directory are not required, but can be specified to
-override them. For example, if you have the following
+preset can be invoked by using the :option:`--preset <cmake --preset>`
+option. If :option:`--preset <cmake --preset>` is specified,
+the generator and build directory are not required, but can be
+specified to override them. For example, if you have the following
``CMakePresets.json`` file:
.. code-block:: json
@@ -502,23 +503,25 @@ command may be invoked in the build directory:
$ cmake --build .
-The ``--build`` flag enables a particular mode of
-operation for the :manual:`cmake(1)` tool. It invokes
-the :variable:`CMAKE_MAKE_PROGRAM` command associated
-with the :manual:`generator <cmake-generators(7)>`, or
+The :option:`--build <cmake --build>` flag enables a
+particular mode of operation for the :manual:`cmake(1)`
+tool. It invokes the :variable:`CMAKE_MAKE_PROGRAM`
+command associated with the
+:manual:`generator <cmake-generators(7)>`, or
the build tool configured by the user.
-The ``--build`` mode also accepts the parameter
-``--target`` to specify a particular target to build,
-for example a particular library, executable or
-custom target, or a particular special target like
-``install``:
+The :option:`--build <cmake --build>` mode also accepts
+the parameter :option:`--target <cmake --target>` to
+specify a particular target to build, for example a
+particular library, executable or custom target, or a
+particular special target like ``install``:
.. code-block:: console
$ cmake --build . --target myexe
-The ``--build`` mode also accepts a ``--config`` parameter
+The :option:`--build <cmake --build>` mode also accepts a
+:option:`--config <cmake --config>` parameter
in the case of multi-config generators to specify which
particular configuration to build:
@@ -526,23 +529,23 @@ particular configuration to build:
$ cmake --build . --target myexe --config Release
-The ``--config`` option has no effect if the generator
-generates a buildsystem specific to a configuration which
-is chosen when invoking cmake with the
-:variable:`CMAKE_BUILD_TYPE` variable.
+The :option:`--config <cmake --config>` option has no
+effect if the generator generates a buildsystem specific
+to a configuration which is chosen when invoking cmake
+with the :variable:`CMAKE_BUILD_TYPE` variable.
Some buildsystems omit details of command lines invoked
-during the build. The ``--verbose`` flag can be used to
-cause those command lines to be shown:
+during the build. The :option:`-verbose <cmake --verbose>`
+flag can be used to cause those command lines to be shown:
.. code-block:: console
$ cmake --build . --target myexe --verbose
-The ``--build`` mode can also pass particular command
-line options to the underlying build tool by listing
-them after ``--``. This can be useful to specify
-options to the build tool, such as to continue the
+The :option:`--build <cmake --build>` mode can also pass
+particular command line options to the underlying build
+tool by listing them after ``--``. This can be useful
+to specify options to the build tool, such as to continue the
build after a failed job, where CMake does not
provide a high-level user interface.
@@ -638,9 +641,9 @@ building the ``foo.i`` target will preprocess both files.
Specifying a Build Program
--------------------------
-The program invoked by the ``--build`` mode is determined
-by the :variable:`CMAKE_MAKE_PROGRAM` variable. For most
-generators, the particular program does not need to be
+The program invoked by the :option:`--build <cmake --build>`
+mode is determined by the :variable:`CMAKE_MAKE_PROGRAM` variable.
+For most generators, the particular program does not need to be
configured.
===================== =========================== ===========================
@@ -661,7 +664,8 @@ The ``jom`` tool is capable of reading makefiles of the
``NMake`` flavor and building in parallel, while the
``nmake`` tool always builds serially. After generating
with the :generator:`NMake Makefiles` generator a user
-can run ``jom`` instead of ``nmake``. The ``--build``
+can run ``jom`` instead of ``nmake``. The
+:option:`--build <cmake --build>`
mode would also use ``jom`` if the
:variable:`CMAKE_MAKE_PROGRAM` was set to ``jom`` while
using the :generator:`NMake Makefiles` generator, and
@@ -671,7 +675,7 @@ and use it as the :variable:`CMAKE_MAKE_PROGRAM`. For
completeness, ``nmake`` is an alternative tool which
can process the output of the
:generator:`NMake Makefiles JOM` generator, but doing
-so would be a pessimisation.
+so would be a pessimization.
Software Installation
=====================
@@ -745,8 +749,8 @@ run only tests without ``Qt`` in their name:
$ ctest -E Qt
-Tests can be run in parallel by passing ``-j`` arguments
-to :manual:`ctest(1)`:
+Tests can be run in parallel by passing :option:`-j <ctest -j>`
+arguments to :manual:`ctest(1)`:
.. code-block:: console
@@ -754,14 +758,15 @@ to :manual:`ctest(1)`:
The environment variable :envvar:`CTEST_PARALLEL_LEVEL`
can alternatively be set to avoid the need to pass
-``-j``.
+:option:`-j <ctest -j>`.
By default :manual:`ctest(1)` does not print the output
-from the tests. The command line argument ``-V`` (or
-``--verbose``) enables verbose mode to print the
+from the tests. The command line argument :option:`-V <ctest -V>`
+(or ``--verbose``) enables verbose mode to print the
output from all tests.
-The ``--output-on-failure`` option prints the test
-output for failing tests only. The environment variable
-:envvar:`CTEST_OUTPUT_ON_FAILURE`
+The :option:`--output-on-failure <ctest --output-on-failure>`
+option prints the test output for failing tests only.
+The environment variable :envvar:`CTEST_OUTPUT_ON_FAILURE`
can be set to ``1`` as an alternative to passing the
-``--output-on-failure`` option to :manual:`ctest(1)`.
+:option:`--output-on-failure <ctest --output-on-failure>`
+option to :manual:`ctest(1)`.
diff --git a/Help/manual/OPTIONS_BUILD.txt b/Help/manual/OPTIONS_BUILD.txt
index 8e23b77..94adac8 100644
--- a/Help/manual/OPTIONS_BUILD.txt
+++ b/Help/manual/OPTIONS_BUILD.txt
@@ -1,12 +1,15 @@
-``-S <path-to-source>``
+.. option:: -S <path-to-source>
+
Path to root directory of the CMake project to build.
-``-B <path-to-build>``
+.. option:: -B <path-to-build>
+
Path to directory which CMake will use as the root of build directory.
If the directory doesn't already exist CMake will make it.
-``-C <initial-cache>``
+.. option:: -C <initial-cache>
+
Pre-load a script to populate the cache.
When CMake is first run in an empty build tree, it creates a
@@ -21,7 +24,8 @@
References to :variable:`CMAKE_SOURCE_DIR` and :variable:`CMAKE_BINARY_DIR`
within the script evaluate to the top-level source and build tree.
-``-D <var>:<type>=<value>, -D <var>=<value>``
+.. option:: -D <var>:<type>=<value>, -D <var>=<value>
+
Create or update a CMake ``CACHE`` entry.
When CMake is first run in an empty build tree, it creates a
@@ -41,7 +45,27 @@
This option may also be given as a single argument:
``-D<var>:<type>=<value>`` or ``-D<var>=<value>``.
-``-U <globbing_expr>``
+ It's important to note that the order of ``-C`` and ``-D`` arguments is
+ significant. They will be carried out in the order they are listed, with the
+ last argument taking precedence over the previous ones. For example, if you
+ specify ``-DCMAKE_BUILD_TYPE=Debug``, followed by a ``-C`` argument with a
+ file that calls:
+
+ .. code-block:: cmake
+
+ set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE)
+
+ then the ``-C`` argument will take precedence, and ``CMAKE_BUILD_TYPE`` will
+ be set to ``Release``. However, if the ``-D`` argument comes after the ``-C``
+ argument, it will be set to ``Debug``.
+
+ If a ``set(... CACHE ...)`` call in the ``-C`` file does not use ``FORCE``,
+ and a ``-D`` argument sets the same variable, the ``-D`` argument will take
+ precedence regardless of order because of the nature of non-``FORCE``
+ ``set(... CACHE ...)`` calls.
+
+.. option:: -U <globbing_expr>
+
Remove matching entries from CMake ``CACHE``.
This option may be used to remove one or more variables from the
@@ -51,7 +75,8 @@
Use with care, you can make your ``CMakeCache.txt`` non-working.
-``-G <generator-name>``
+.. option:: -G <generator-name>
+
Specify a build system generator.
CMake may support multiple native build systems on certain
@@ -62,73 +87,85 @@
If not specified, CMake checks the :envvar:`CMAKE_GENERATOR` environment
variable and otherwise falls back to a builtin default selection.
-``-T <toolset-spec>``
+.. option:: -T <toolset-spec>
+
Toolset specification for the generator, if supported.
Some CMake generators support a toolset specification to tell
the native build system how to choose a compiler. See the
:variable:`CMAKE_GENERATOR_TOOLSET` variable for details.
-``-A <platform-name>``
+.. option:: -A <platform-name>
+
Specify platform name if supported by generator.
Some CMake generators support a platform name to be given to the
native build system to choose a compiler or SDK. See the
:variable:`CMAKE_GENERATOR_PLATFORM` variable for details.
-``--toolchain <path-to-file>``
+.. option:: --toolchain <path-to-file>
+
Specify the cross compiling toolchain file, equivalent to setting
:variable:`CMAKE_TOOLCHAIN_FILE` variable.
-``--install-prefix <directory>``
+.. option:: --install-prefix <directory>
+
Specify the installation directory, used by the
:variable:`CMAKE_INSTALL_PREFIX` variable. Must be an absolute path.
-``-Wno-dev``
+.. option:: -Wno-dev
+
Suppress developer warnings.
Suppress warnings that are meant for the author of the
``CMakeLists.txt`` files. By default this will also turn off
deprecation warnings.
-``-Wdev``
+.. option:: -Wdev
+
Enable developer warnings.
Enable warnings that are meant for the author of the ``CMakeLists.txt``
files. By default this will also turn on deprecation warnings.
-``-Werror=dev``
- Make developer warnings errors.
-
- Make warnings that are meant for the author of the ``CMakeLists.txt`` files
- errors. By default this will also turn on deprecated warnings as errors.
+.. option:: -Wdeprecated
-``-Wno-error=dev``
- Make developer warnings not errors.
-
- Make warnings that are meant for the author of the ``CMakeLists.txt`` files not
- errors. By default this will also turn off deprecated warnings as errors.
-
-``-Wdeprecated``
Enable deprecated functionality warnings.
Enable warnings for usage of deprecated functionality, that are meant
for the author of the ``CMakeLists.txt`` files.
-``-Wno-deprecated``
+.. option:: -Wno-deprecated
+
Suppress deprecated functionality warnings.
Suppress warnings for usage of deprecated functionality, that are meant
for the author of the ``CMakeLists.txt`` files.
-``-Werror=deprecated``
- Make deprecated macro and function warnings errors.
+.. option:: -Werror=<what>
+
+ Treat CMake warnings as errors. ``<what>`` must be one of the following:
+
+ ``dev``
+ Make developer warnings errors.
+
+ Make warnings that are meant for the author of the ``CMakeLists.txt`` files
+ errors. By default this will also turn on deprecated warnings as errors.
+
+ ``deprecated``
+ Make deprecated macro and function warnings errors.
+
+ Make warnings for usage of deprecated macros and functions, that are meant
+ for the author of the ``CMakeLists.txt`` files, errors.
+
+.. option:: -Wno-error=<what>
- Make warnings for usage of deprecated macros and functions, that are meant
- for the author of the ``CMakeLists.txt`` files, errors.
+ Do not treat CMake warnings as errors. ``<what>`` must be one of the following:
-``-Wno-error=deprecated``
- Make deprecated macro and function warnings not errors.
+ ``dev``
+ Make warnings that are meant for the author of the ``CMakeLists.txt`` files not
+ errors. By default this will also turn off deprecated warnings as errors.
- Make warnings for usage of deprecated macros and functions, that are meant
- for the author of the ``CMakeLists.txt`` files, not errors.
+ ``deprecated``
+ Make warnings for usage of deprecated macros and functions, that are meant
+ for the author of the ``CMakeLists.txt`` files, not errors.
diff --git a/Help/manual/OPTIONS_HELP.txt b/Help/manual/OPTIONS_HELP.txt
index feeca7d..78ee245 100644
--- a/Help/manual/OPTIONS_HELP.txt
+++ b/Help/manual/OPTIONS_HELP.txt
@@ -1,134 +1,152 @@
-.. |file| replace:: The help is printed to a named <f>ile if given.
+.. |file| replace:: The output is printed to a named ``<file>`` if given.
+
+.. option:: -version [<file>], --version [<file>], /V [<file>]
+
+ Show program name/version banner and exit.
+ |file|
+
+.. option:: -h, -H, --help, -help, -usage, /?
-``--help,-help,-usage,-h,-H,/?``
Print usage information and exit.
Usage describes the basic command line interface and its options.
-``--version,-version,/V [<f>]``
- Show program name/version banner and exit.
+.. option:: --help-full [<file>]
- If a file is specified, the version is written into it.
- |file|
-
-``--help-full [<f>]``
Print all help manuals and exit.
All manuals are printed in a human-readable text format.
|file|
-``--help-manual <man> [<f>]``
+.. option:: --help-manual <man> [<file>]
+
Print one help manual and exit.
The specified manual is printed in a human-readable text format.
|file|
-``--help-manual-list [<f>]``
+.. option:: --help-manual-list [<file>]
+
List help manuals available and exit.
The list contains all manuals for which help may be obtained by
using the ``--help-manual`` option followed by a manual name.
|file|
-``--help-command <cmd> [<f>]``
+.. option:: --help-command <cmd> [<file>]
+
Print help for one command and exit.
The :manual:`cmake-commands(7)` manual entry for ``<cmd>`` is
printed in a human-readable text format.
|file|
-``--help-command-list [<f>]``
+.. option:: --help-command-list [<file>]
+
List commands with help available and exit.
The list contains all commands for which help may be obtained by
using the ``--help-command`` option followed by a command name.
|file|
-``--help-commands [<f>]``
+.. option:: --help-commands [<file>]
+
Print cmake-commands manual and exit.
The :manual:`cmake-commands(7)` manual is printed in a
human-readable text format.
|file|
-``--help-module <mod> [<f>]``
+.. option:: --help-module <mod> [<file>]
+
Print help for one module and exit.
The :manual:`cmake-modules(7)` manual entry for ``<mod>`` is printed
in a human-readable text format.
|file|
-``--help-module-list [<f>]``
+.. option:: --help-module-list [<file>]
+
List modules with help available and exit.
The list contains all modules for which help may be obtained by
using the ``--help-module`` option followed by a module name.
|file|
-``--help-modules [<f>]``
+.. option:: --help-modules [<file>]
+
Print cmake-modules manual and exit.
The :manual:`cmake-modules(7)` manual is printed in a human-readable
text format.
|file|
-``--help-policy <cmp> [<f>]``
+.. option:: --help-policy <cmp> [<file>]
+
Print help for one policy and exit.
The :manual:`cmake-policies(7)` manual entry for ``<cmp>`` is
printed in a human-readable text format.
|file|
-``--help-policy-list [<f>]``
+.. option:: --help-policy-list [<file>]
+
List policies with help available and exit.
The list contains all policies for which help may be obtained by
using the ``--help-policy`` option followed by a policy name.
|file|
-``--help-policies [<f>]``
+.. option:: --help-policies [<file>]
+
Print cmake-policies manual and exit.
The :manual:`cmake-policies(7)` manual is printed in a
human-readable text format.
|file|
-``--help-property <prop> [<f>]``
+.. option:: --help-property <prop> [<file>]
+
Print help for one property and exit.
The :manual:`cmake-properties(7)` manual entries for ``<prop>`` are
printed in a human-readable text format.
|file|
-``--help-property-list [<f>]``
+.. option:: --help-property-list [<file>]
+
List properties with help available and exit.
The list contains all properties for which help may be obtained by
using the ``--help-property`` option followed by a property name.
|file|
-``--help-properties [<f>]``
+.. option:: --help-properties [<file>]
+
Print cmake-properties manual and exit.
The :manual:`cmake-properties(7)` manual is printed in a
human-readable text format.
|file|
-``--help-variable <var> [<f>]``
+.. option:: --help-variable <var> [<file>]
+
Print help for one variable and exit.
The :manual:`cmake-variables(7)` manual entry for ``<var>`` is
printed in a human-readable text format.
|file|
-``--help-variable-list [<f>]``
+.. option:: --help-variable-list [<file>]
+
List variables with help available and exit.
The list contains all variables for which help may be obtained by
using the ``--help-variable`` option followed by a variable name.
|file|
-``--help-variables [<f>]``
+.. option:: --help-variables [<file>]
+
Print cmake-variables manual and exit.
The :manual:`cmake-variables(7)` manual is printed in a
diff --git a/Help/manual/ccmake.1.rst b/Help/manual/ccmake.1.rst
index 60d45a3..cd66d51 100644
--- a/Help/manual/ccmake.1.rst
+++ b/Help/manual/ccmake.1.rst
@@ -8,7 +8,7 @@ Synopsis
.. parsed-literal::
- ccmake [<options>] {<path-to-source> | <path-to-existing-build>}
+ ccmake [<options>] <path-to-source | path-to-existing-build>
Description
===========
@@ -27,6 +27,8 @@ native tool on their platform.
Options
=======
+.. program:: ccmake
+
.. include:: OPTIONS_BUILD.txt
.. include:: OPTIONS_HELP.txt
diff --git a/Help/manual/cmake-commands.7.rst b/Help/manual/cmake-commands.7.rst
index 036fa8f..0f35632 100644
--- a/Help/manual/cmake-commands.7.rst
+++ b/Help/manual/cmake-commands.7.rst
@@ -15,6 +15,7 @@ These commands are always available.
.. toctree::
:maxdepth: 1
+ /command/block
/command/break
/command/cmake_host_system_information
/command/cmake_language
@@ -26,6 +27,7 @@ These commands are always available.
/command/continue
/command/else
/command/elseif
+ /command/endblock
/command/endforeach
/command/endfunction
/command/endif
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst
index 7a6188a..a8faa2a 100644
--- a/Help/manual/cmake-generator-expressions.7.rst
+++ b/Help/manual/cmake-generator-expressions.7.rst
@@ -594,6 +594,10 @@ Configuration Expressions
expression when it is evaluated on a property of an :prop_tgt:`IMPORTED`
target.
+ .. versionchanged:: 3.19
+ Multiple configurations can be specified for ``cfgs``.
+ CMake 3.18 and earlier only accepted a single configuration.
+
.. genex:: $<OUTPUT_CONFIG:...>
.. versionadded:: 3.20
diff --git a/Help/manual/cmake-generators.7.rst b/Help/manual/cmake-generators.7.rst
index 034e218..ed5bbbf 100644
--- a/Help/manual/cmake-generators.7.rst
+++ b/Help/manual/cmake-generators.7.rst
@@ -18,11 +18,11 @@ as a variant of some of the `Command-Line Build Tool Generators`_ to
produce project files for an auxiliary IDE.
CMake Generators are platform-specific so each may be available only
-on certain platforms. The :manual:`cmake(1)` command-line tool ``--help``
-output lists available generators on the current platform. Use its ``-G``
-option to specify the generator for a new build tree.
-The :manual:`cmake-gui(1)` offers interactive selection of a generator
-when creating a new build tree.
+on certain platforms. The :manual:`cmake(1)` command-line tool
+:option:`--help <cmake --help>` output lists available generators on the
+current platform. Use its :option:`-G <cmake -G>` option to specify the
+generator for a new build tree. The :manual:`cmake-gui(1)` offers
+interactive selection of a generator when creating a new build tree.
CMake Generators
================
@@ -108,9 +108,9 @@ Extra Generators
================
Some of the `CMake Generators`_ listed in the :manual:`cmake(1)`
-command-line tool ``--help`` output may have variants that specify
-an extra generator for an auxiliary IDE tool. Such generator
-names have the form ``<extra-generator> - <main-generator>``.
+command-line tool :option:`--help <cmake --help>` output may have
+variants that specify an extra generator for an auxiliary IDE tool.
+Such generator names have the form ``<extra-generator> - <main-generator>``.
The following extra generators are known to CMake.
.. toctree::
diff --git a/Help/manual/cmake-gui.1.rst b/Help/manual/cmake-gui.1.rst
index 281986f..dd0eeca 100644
--- a/Help/manual/cmake-gui.1.rst
+++ b/Help/manual/cmake-gui.1.rst
@@ -9,7 +9,7 @@ Synopsis
.. parsed-literal::
cmake-gui [<options>]
- cmake-gui [<options>] {<path-to-source> | <path-to-existing-build>}
+ cmake-gui [<options>] <path-to-source | path-to-existing-build>
cmake-gui [<options>] -S <path-to-source> -B <path-to-build>
cmake-gui [<options>] --browse-manual
@@ -29,19 +29,25 @@ native tool on their platform.
Options
=======
-``-S <path-to-source>``
+.. program:: cmake-gui
+
+.. option:: -S <path-to-source>
+
Path to root directory of the CMake project to build.
-``-B <path-to-build>``
+.. option:: -B <path-to-build>
+
Path to directory which CMake will use as the root of build directory.
If the directory doesn't already exist CMake will make it.
-``--preset=<preset-name>``
+.. option:: --preset=<preset-name>
+
Name of the preset to use from the project's
:manual:`presets <cmake-presets(7)>` files, if it has them.
-``--browse-manual``
+.. option:: --browse-manual
+
Open the CMake reference manual in a browser and immediately exit.
.. include:: OPTIONS_HELP.txt
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index 93beea9..d161a28 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -193,6 +193,7 @@ They are normally called through the :command:`find_package` command.
/module/FindOpenGL
/module/FindOpenMP
/module/FindOpenSceneGraph
+ /module/FindOpenSP
/module/FindOpenSSL
/module/FindOpenThreads
/module/Findosg
@@ -236,6 +237,7 @@ They are normally called through the :command:`find_package` command.
/module/FindRuby
/module/FindSDL
/module/FindSDL_image
+ /module/FindSDL_gfx
/module/FindSDL_mixer
/module/FindSDL_net
/module/FindSDL_sound
diff --git a/Help/manual/cmake-policies.7.rst b/Help/manual/cmake-policies.7.rst
index f6ab0c7..a1133b9 100644
--- a/Help/manual/cmake-policies.7.rst
+++ b/Help/manual/cmake-policies.7.rst
@@ -52,6 +52,14 @@ to determine whether to report an error on use of deprecated macros or
functions.
+Policies Introduced by CMake 3.25
+=================================
+
+.. toctree::
+ :maxdepth: 1
+
+ CMP0140: The return() command checks its arguments. </policy/CMP0140>
+
Policies Introduced by CMake 3.24
=================================
diff --git a/Help/manual/cmake-presets.7.rst b/Help/manual/cmake-presets.7.rst
index a96c704..35dac76 100644
--- a/Help/manual/cmake-presets.7.rst
+++ b/Help/manual/cmake-presets.7.rst
@@ -19,10 +19,10 @@ supports files included with the ``include`` field.
``CMakePresets.json`` and ``CMakeUserPresets.json`` live in the project's root
directory. They both have exactly the same format, and both are optional
-(though at least one must be present if ``--preset`` is specified).
-``CMakePresets.json`` is meant to specify project-wide build details, while
-``CMakeUserPresets.json`` is meant for developers to specify their own local
-build details.
+(though at least one must be present if :option:`--preset <cmake --preset>`
+is specified). ``CMakePresets.json`` is meant to specify project-wide build
+details, while ``CMakeUserPresets.json`` is meant for developers to specify
+their own local build details.
``CMakePresets.json`` may be checked into a version control system, and
``CMakeUserPresets.json`` should NOT be checked in. For example, if a
@@ -40,7 +40,6 @@ The files are a JSON document with an object as the root:
The root object recognizes the following fields:
``version``
-
A required integer representing the version of the JSON schema.
The supported versions are:
@@ -59,32 +58,29 @@ The root object recognizes the following fields:
``5``
.. versionadded:: 3.24
-``cmakeMinimumRequired``
+ ``6``
+ .. versionadded:: 3.25
+``cmakeMinimumRequired``
An optional object representing the minimum version of CMake needed to
build this project. This object consists of the following fields:
``major``
-
An optional integer representing the major version.
``minor``
-
An optional integer representing the minor version.
``patch``
-
An optional integer representing the patch version.
``include``
-
An optional array of strings representing files to include. If the filenames
are not absolute, they are considered relative to the current file.
This is allowed in preset files specifying version ``4`` or above.
See `Includes`_ for discussion of the constraints on included files.
``vendor``
-
An optional map containing vendor-specific information. CMake does not
interpret the contents of this field except to verify that it is a map if
it does exist. However, the keys should be a vendor-specific domain name
@@ -93,17 +89,14 @@ The root object recognizes the following fields:
desired by the vendor, though will typically be a map.
``configurePresets``
-
An optional array of `Configure Preset`_ objects.
This is allowed in preset files specifying version ``1`` or above.
``buildPresets``
-
An optional array of `Build Preset`_ objects.
This is allowed in preset files specifying version ``2`` or above.
``testPresets``
-
An optional array of `Test Preset`_ objects.
This is allowed in preset files specifying version ``2`` or above.
@@ -134,15 +127,14 @@ Each entry of the ``configurePresets`` array is a JSON object
that may contain the following fields:
``name``
-
A required string representing the machine-friendly name of the preset.
This identifier is used in the :ref:`cmake --preset <CMake Options>` option.
There must not be two configure presets in the union of ``CMakePresets.json``
and ``CMakeUserPresets.json`` in the same directory with the same name.
- However, a configure preset may have the same name as a build or test preset.
+ However, a configure preset may have the same name as a build, test, or
+ package preset.
``hidden``
-
An optional boolean specifying whether or not a preset should be hidden.
If a preset is hidden, it cannot be used in the ``--preset=`` argument,
will not show up in the :manual:`CMake GUI <cmake-gui(1)>`, and does not
@@ -151,7 +143,6 @@ that may contain the following fields:
other presets to inherit via the ``inherits`` field.
``inherits``
-
An optional array of strings representing the names of presets to inherit
from. This field can also be a string, which is equivalent to an array
containing one string.
@@ -169,12 +160,10 @@ that may contain the following fields:
``CMakeUserPresets.json``.
``condition``
-
An optional `Condition`_ object. This is allowed in preset files specifying
version ``3`` or above.
``vendor``
-
An optional map containing vendor-specific information. CMake does not
interpret the contents of this field except to verify that it is a map
if it does exist. However, it should follow the same conventions as the
@@ -183,47 +172,39 @@ that may contain the following fields:
when appropriate.
``displayName``
-
An optional string with a human-friendly name of the preset.
``description``
-
An optional string with a human-friendly description of the preset.
``generator``
-
An optional string representing the generator to use for the preset. If
``generator`` is not specified, it must be inherited from the
``inherits`` preset (unless this preset is ``hidden``). In version ``3``
or above, this field may be omitted to fall back to regular generator
discovery procedure.
- Note that for Visual Studio generators, unlike in the command line ``-G``
- argument, you cannot include the platform name in the generator name. Use
- the ``architecture`` field instead.
+ Note that for Visual Studio generators, unlike in the command line
+ :option:`-G <cmake -G>` argument, you cannot include the platform name
+ in the generator name. Use the ``architecture`` field instead.
``architecture``, ``toolset``
-
Optional fields representing the platform and toolset, respectively, for
generators that support them. Each may be either a string or an object
with the following fields:
``value``
-
An optional string representing the value.
``strategy``
-
An optional string telling CMake how to handle the ``architecture`` or
``toolset`` field. Valid values are:
``"set"``
-
Set the respective value. This will result in an error for generators
that do not support the respective field.
``"external"``
-
Do not set the value, even if the generator supports it. This is
useful if, for example, a preset uses the Ninja generator, and an IDE
knows how to set up the Visual C++ environment from the
@@ -232,7 +213,6 @@ that may contain the following fields:
before invoking CMake.
``toolchainFile``
-
An optional string representing the path to the toolchain file.
This field supports `macro expansion`_. If a relative path is specified,
it is calculated relative to the build directory, and if not found,
@@ -241,7 +221,6 @@ that may contain the following fields:
specifying version ``3`` or above.
``binaryDir``
-
An optional string representing the path to the output binary directory.
This field supports `macro expansion`_. If a relative path is specified,
it is calculated relative to the source directory. If ``binaryDir`` is not
@@ -250,20 +229,17 @@ that may contain the following fields:
omitted.
``installDir``
-
An optional string representing the path to the installation directory.
This field supports `macro expansion`_. If a relative path is specified,
it is calculated relative to the source directory. This is allowed in
preset files specifying version ``3`` or above.
``cmakeExecutable``
-
An optional string representing the path to the CMake executable to use
for this preset. This is reserved for use by IDEs, and is not used by
CMake itself. IDEs that use this field should expand any macros in it.
``cacheVariables``
-
An optional map of cache variables. The key is the variable name (which
may not be an empty string), and the value is either ``null``, a boolean
(which is equivalent to a value of ``"TRUE"`` or ``"FALSE"`` and a type
@@ -271,11 +247,9 @@ that may contain the following fields:
supports `macro expansion`_), or an object with the following fields:
``type``
-
An optional string representing the type of the variable.
``value``
-
A required string or boolean representing the value of the variable.
A boolean is equivalent to ``"TRUE"`` or ``"FALSE"``. This field
supports `macro expansion`_.
@@ -288,7 +262,6 @@ that may contain the following fields:
a value was inherited from another preset.
``environment``
-
An optional map of environment variables. The key is the variable name
(which may not be an empty string), and the value is either ``null`` or
a string representing the value of the variable. Each variable is set
@@ -306,73 +279,68 @@ that may contain the following fields:
a value was inherited from another preset.
``warnings``
-
An optional object specifying the warnings to enable. The object may
contain the following fields:
``dev``
-
- An optional boolean. Equivalent to passing ``-Wdev`` or ``-Wno-dev``
- on the command line. This may not be set to ``false`` if ``errors.dev``
- is set to ``true``.
+ An optional boolean. Equivalent to passing :option:`-Wdev <cmake -Wdev>`
+ or :option:`-Wno-dev <cmake -Wno-dev>` on the command line. This may not
+ be set to ``false`` if ``errors.dev`` is set to ``true``.
``deprecated``
-
- An optional boolean. Equivalent to passing ``-Wdeprecated`` or
- ``-Wno-deprecated`` on the command line. This may not be set to
- ``false`` if ``errors.deprecated`` is set to ``true``.
+ An optional boolean. Equivalent to passing
+ :option:`-Wdeprecated <cmake -Wdeprecated>` or
+ :option:`-Wno-deprecated <cmake -Wno-deprecated>` on the command line.
+ This may not be set to ``false`` if ``errors.deprecated`` is set to
+ ``true``.
``uninitialized``
-
An optional boolean. Setting this to ``true`` is equivalent to passing
- ``--warn-uninitialized`` on the command line.
+ :option:`--warn-uninitialized <cmake --warn-uninitialized>` on the command
+ line.
``unusedCli``
-
An optional boolean. Setting this to ``false`` is equivalent to passing
- ``--no-warn-unused-cli`` on the command line.
+ :option:`--no-warn-unused-cli <cmake --no-warn-unused-cli>` on the command
+ line.
``systemVars``
-
An optional boolean. Setting this to ``true`` is equivalent to passing
- ``--check-system-vars`` on the command line.
+ :option:`--check-system-vars <cmake --check-system-vars>` on the command
+ line.
``errors``
-
An optional object specifying the errors to enable. The object may
contain the following fields:
``dev``
-
- An optional boolean. Equivalent to passing ``-Werror=dev`` or
- ``-Wno-error=dev`` on the command line. This may not be set to ``true``
- if ``warnings.dev`` is set to ``false``.
+ An optional boolean. Equivalent to passing :option:`-Werror=dev <cmake -Werror>`
+ or :option:`-Wno-error=dev <cmake -Werror>` on the command line.
+ This may not be set to ``true`` if ``warnings.dev`` is set to ``false``.
``deprecated``
-
- An optional boolean. Equivalent to passing ``-Werror=deprecated`` or
- ``-Wno-error=deprecated`` on the command line. This may not be set to
- ``true`` if ``warnings.deprecated`` is set to ``false``.
+ An optional boolean. Equivalent to passing
+ :option:`-Werror=deprecated <cmake -Werror>` or
+ :option:`-Wno-error=deprecated <cmake -Werror>` on the command line.
+ This may not be set to ``true`` if ``warnings.deprecated`` is set to
+ ``false``.
``debug``
-
An optional object specifying debug options. The object may contain the
following fields:
``output``
-
An optional boolean. Setting this to ``true`` is equivalent to passing
- ``--debug-output`` on the command line.
+ :option:`--debug-output <cmake --debug-output>` on the command line.
``tryCompile``
-
An optional boolean. Setting this to ``true`` is equivalent to passing
- ``--debug-trycompile`` on the command line.
+ :option:`--debug-trycompile <cmake --debug-trycompile>` on the command
+ line.
``find``
-
An optional boolean. Setting this to ``true`` is equivalent to passing
- ``--debug-find`` on the command line.
+ :option:`--debug-find <cmake --debug-find>` on the command line.
Build Preset
^^^^^^^^^^^^
@@ -381,24 +349,23 @@ Each entry of the ``buildPresets`` array is a JSON object
that may contain the following fields:
``name``
-
A required string representing the machine-friendly name of the preset.
This identifier is used in the
:ref:`cmake --build --preset <Build Tool Mode>` option.
There must not be two build presets in the union of ``CMakePresets.json``
and ``CMakeUserPresets.json`` in the same directory with the same name.
- However, a build preset may have the same name as a configure or test preset.
+ However, a build preset may have the same name as a configure, test, or
+ package preset.
``hidden``
-
An optional boolean specifying whether or not a preset should be hidden.
- If a preset is hidden, it cannot be used in the ``--preset`` argument
+ If a preset is hidden, it cannot be used in the
+ :option:`--preset <cmake --preset>` argument
and does not have to have a valid ``configurePreset``, even from
inheritance. ``hidden`` presets are intended to be used as a base for
other presets to inherit via the ``inherits`` field.
``inherits``
-
An optional array of strings representing the names of presets to inherit
from. This field can also be a string, which is equivalent to an array
containing one string.
@@ -416,12 +383,10 @@ that may contain the following fields:
``CMakeUserPresets.json``.
``condition``
-
An optional `Condition`_ object. This is allowed in preset files specifying
version ``3`` or above.
``vendor``
-
An optional map containing vendor-specific information. CMake does not
interpret the contents of this field except to verify that it is a map
if it does exist. However, it should follow the same conventions as the
@@ -430,15 +395,12 @@ that may contain the following fields:
when appropriate.
``displayName``
-
An optional string with a human-friendly name of the preset.
``description``
-
An optional string with a human-friendly description of the preset.
``environment``
-
An optional map of environment variables. The key is the variable name
(which may not be an empty string), and the value is either ``null`` or
a string representing the value of the variable. Each variable is set
@@ -469,7 +431,6 @@ that may contain the following fields:
project.
``configurePreset``
-
An optional string specifying the name of a configure preset to
associate with this build preset. If ``configurePreset`` is not
specified, it must be inherited from the inherits preset (unless this
@@ -478,36 +439,30 @@ that may contain the following fields:
configuration did.
``inheritConfigureEnvironment``
-
An optional boolean that defaults to true. If true, the environment
variables from the associated configure preset are inherited after all
inherited build preset environments, but before environment variables
explicitly specified in this build preset.
``jobs``
-
- An optional integer. Equivalent to passing ``--parallel`` or ``-j`` on
- the command line.
+ An optional integer. Equivalent to passing
+ :option:`--parallel <cmake --parallel>` or ``-j`` on the command line.
``targets``
-
An optional string or array of strings. Equivalent to passing
- ``--target`` or ``-t`` on the command line. Vendors may ignore the
- targets property or hide build presets that explicitly specify targets.
- This field supports macro expansion.
+ :option:`--target <cmake --target>` or ``-t`` on the command line.
+ Vendors may ignore the targets property or hide build presets that
+ explicitly specify targets. This field supports macro expansion.
``configuration``
-
- An optional string. Equivalent to passing ``--config`` on the command
- line.
+ An optional string. Equivalent to passing :option:`--config <cmake --config>`
+ on the command line.
``cleanFirst``
-
- An optional bool. If true, equivalent to passing ``--clean-first`` on
- the command line.
+ An optional bool. If true, equivalent to passing
+ :option:`--clean-first <cmake --clean-first>` on the command line.
``resolvePackageReferences``
-
An optional string that specifies the package resolve mode. This is
allowed in preset files specifying version ``4`` or above.
@@ -517,24 +472,23 @@ that may contain the following fields:
package references, this option does nothing. Valid values are:
``on``
-
Causes package references to be resolved before attempting a build.
``off``
-
Package references will not be resolved. Note that this may cause
errors in some build environments, such as .NET SDK style projects.
``only``
-
Only resolve package references, but do not perform a build.
.. note::
- The command line parameter ``--resolve-package-references`` will take
- priority over this setting. If the command line parameter is not provided
- and this setting is not specified, an environment-specific cache variable
- will be evaluated to decide, if package restoration should be performed.
+ The command line parameter
+ :option:`--resolve-package-references <cmake --resolve-package-references>`
+ will take priority over this setting. If the command line parameter is not
+ provided and this setting is not specified, an environment-specific cache
+ variable will be evaluated to decide, if package restoration should be
+ performed.
When using the Visual Studio generator, package references are defined
using the :prop_tgt:`VS_PACKAGE_REFERENCES` property. Package references
@@ -543,12 +497,10 @@ that may contain the following fields:
done from within a configure preset.
``verbose``
-
- An optional bool. If true, equivalent to passing ``--verbose`` on the
- command line.
+ An optional bool. If true, equivalent to passing
+ :option:`--verbose <cmake --verbose>` on the command line.
``nativeToolOptions``
-
An optional array of strings. Equivalent to passing options after ``--``
on the command line. The array values support macro expansion.
@@ -559,23 +511,22 @@ Each entry of the ``testPresets`` array is a JSON object
that may contain the following fields:
``name``
-
A required string representing the machine-friendly name of the preset.
- This identifier is used in the :ref:`ctest --preset <CTest Options>` option.
+ This identifier is used in the :option:`ctest --preset` option.
There must not be two test presets in the union of ``CMakePresets.json``
and ``CMakeUserPresets.json`` in the same directory with the same name.
- However, a test preset may have the same name as a configure or build preset.
+ However, a test preset may have the same name as a configure, build, or
+ package preset.
``hidden``
-
An optional boolean specifying whether or not a preset should be hidden.
- If a preset is hidden, it cannot be used in the ``--preset`` argument
+ If a preset is hidden, it cannot be used in the
+ :option:`--preset <ctest --preset>` argument
and does not have to have a valid ``configurePreset``, even from
inheritance. ``hidden`` presets are intended to be used as a base for
other presets to inherit via the ``inherits`` field.
``inherits``
-
An optional array of strings representing the names of presets to inherit
from. This field can also be a string, which is equivalent to an array
containing one string.
@@ -593,12 +544,10 @@ that may contain the following fields:
``CMakeUserPresets.json``.
``condition``
-
An optional `Condition`_ object. This is allowed in preset files specifying
version ``3`` or above.
``vendor``
-
An optional map containing vendor-specific information. CMake does not
interpret the contents of this field except to verify that it is a map
if it does exist. However, it should follow the same conventions as the
@@ -607,15 +556,12 @@ that may contain the following fields:
when appropriate.
``displayName``
-
An optional string with a human-friendly name of the preset.
``description``
-
An optional string with a human-friendly description of the preset.
``environment``
-
An optional map of environment variables. The key is the variable name
(which may not be an empty string), and the value is either ``null`` or
a string representing the value of the variable. Each variable is set
@@ -633,7 +579,6 @@ that may contain the following fields:
even if a value was inherited from another preset.
``configurePreset``
-
An optional string specifying the name of a configure preset to
associate with this test preset. If ``configurePreset`` is not
specified, it must be inherited from the inherits preset (unless this
@@ -642,233 +587,204 @@ that may contain the following fields:
configuration did and build did.
``inheritConfigureEnvironment``
-
An optional boolean that defaults to true. If true, the environment
variables from the associated configure preset are inherited after all
inherited test preset environments, but before environment variables
explicitly specified in this test preset.
``configuration``
-
- An optional string. Equivalent to passing ``--build-config`` on the
- command line.
+ An optional string. Equivalent to passing
+ :option:`--build-config <ctest --build-config>` on the command line.
``overwriteConfigurationFile``
-
An optional array of configuration options to overwrite options
specified in the CTest configuration file. Equivalent to passing
- ``--overwrite`` for each value in the array. The array values
- support macro expansion.
+ :option:`--overwrite <ctest --overwrite>` for each value in the array.
+ The array values support macro expansion.
``output``
-
An optional object specifying output options. The object may contain the
following fields.
``shortProgress``
-
- An optional bool. If true, equivalent to passing ``--progress`` on the
- command line.
+ An optional bool. If true, equivalent to passing
+ :option:`--progress <ctest --progress>` on the command line.
``verbosity``
-
An optional string specifying verbosity level. Must be one of the
following:
``default``
-
Equivalent to passing no verbosity flags on the command line.
``verbose``
-
- Equivalent to passing ``--verbose`` on the command line.
+ Equivalent to passing :option:`--verbose <ctest --verbose>` on
+ the command line.
``extra``
-
- Equivalent to passing ``--extra-verbose`` on the command line.
+ Equivalent to passing :option:`--extra-verbose <ctest --extra-verbose>`
+ on the command line.
``debug``
-
- An optional bool. If true, equivalent to passing ``--debug`` on the
- command line.
+ An optional bool. If true, equivalent to passing
+ :option:`--debug <ctest --debug>` on the command line.
``outputOnFailure``
-
An optional bool. If true, equivalent to passing
- ``--output-on-failure`` on the command line.
+ :option:`--output-on-failure <ctest --output-on-failure>` on the command
+ line.
``quiet``
-
- An optional bool. If true, equivalent to passing ``--quiet`` on the
- command line.
+ An optional bool. If true, equivalent to passing
+ :option:`--quiet <ctest --quiet>` on the command line.
``outputLogFile``
-
An optional string specifying a path to a log file. Equivalent to
- passing ``--output-log`` on the command line. This field supports
- macro expansion.
+ passing :option:`--output-log <ctest --output-log>` on the command line.
+ This field supports macro expansion.
``labelSummary``
-
An optional bool. If false, equivalent to passing
- ``--no-label-summary`` on the command line.
+ :option:`--no-label-summary <ctest --no-label-summary>` on the command
+ line.
``subprojectSummary``
-
An optional bool. If false, equivalent to passing
- ``--no-subproject-summary`` on the command line.
+ :option:`--no-subproject-summary <ctest --no-subproject-summary>`
+ on the command line.
``maxPassedTestOutputSize``
-
An optional integer specifying the maximum output for passed tests in
- bytes. Equivalent to passing ``--test-output-size-passed`` on the
- command line.
+ bytes. Equivalent to passing
+ :option:`--test-output-size-passed <ctest --test-output-size-passed>`
+ on the command line.
``maxFailedTestOutputSize``
-
An optional integer specifying the maximum output for failed tests in
- bytes. Equivalent to passing ``--test-output-size-failed`` on the
- command line.
+ bytes. Equivalent to passing
+ :option:`--test-output-size-failed <ctest --test-output-size-failed>`
+ on the command line.
``testOutputTruncation``
-
An optional string specifying the test output truncation mode. Equivalent
- to passing ``--test-output-truncation`` on the command line."
- This is allowed in preset files specifying version ``5`` or above.
+ to passing
+ :option:`--test-output-truncation <ctest --test-output-truncation>` on
+ the command line. This is allowed in preset files specifying version
+ ``5`` or above.
``maxTestNameWidth``
-
An optional integer specifying the maximum width of a test name to
- output. Equivalent to passing ``--max-width`` on the command line.
+ output. Equivalent to passing :option:`--max-width <ctest --max-width>`
+ on the command line.
``filter``
-
An optional object specifying how to filter the tests to run. The object
may contain the following fields.
``include``
-
An optional object specifying which tests to include. The object may
contain the following fields.
``name``
-
An optional string specifying a regex for test names. Equivalent to
- passing ``--tests-regex`` on the command line. This field supports
- macro expansion. CMake regex syntax is described under
- :ref:`string(REGEX) <Regex Specification>`.
-
+ passing :option:`--tests-regex <ctest --tests-regex>` on the command
+ line. This field supports macro expansion. CMake regex syntax is
+ described under :ref:`string(REGEX) <Regex Specification>`.
``label``
-
An optional string specifying a regex for test labels. Equivalent to
- passing ``--label-regex`` on the command line. This field supports
- macro expansion.
+ passing :option:`--label-regex <ctest --label-regex>` on the command
+ line. This field supports macro expansion.
``useUnion``
-
- An optional bool. Equivalent to passing ``--union`` on the command
- line.
+ An optional bool. Equivalent to passing :option:`--union <ctest --union>`
+ on the command line.
``index``
-
An optional object specifying tests to include by test index. The
object may contain the following fields. Can also be an optional
string specifying a file with the command line syntax for
- ``--tests-information``. If specified as a string, this field
- supports macro expansion.
+ :option:`--tests-information <ctest --tests-information>`.
+ If specified as a string, this field supports macro expansion.
``start``
-
An optional integer specifying a test index to start testing at.
``end``
-
An optional integer specifying a test index to stop testing at.
``stride``
-
An optional integer specifying the increment.
``specificTests``
-
An optional array of integers specifying specific test indices to
run.
``exclude``
-
An optional object specifying which tests to exclude. The object may
contain the following fields.
``name``
-
An optional string specifying a regex for test names. Equivalent to
- passing ``--exclude-regex`` on the command line. This field supports
- macro expansion.
+ passing :option:`--exclude-regex <ctest --exclude-regex>` on the
+ command line. This field supports macro expansion.
``label``
-
An optional string specifying a regex for test labels. Equivalent to
- passing ``--label-exclude`` on the command line. This field supports
- macro expansion.
+ passing :option:`--label-exclude <ctest --label-exclude>` on the
+ command line. This field supports macro expansion.
``fixtures``
-
An optional object specifying which fixtures to exclude from adding
tests. The object may contain the following fields.
``any``
-
An optional string specifying a regex for text fixtures to exclude
- from adding any tests. Equivalent to ``--fixture-exclude-any`` on
+ from adding any tests. Equivalent to
+ :option:`--fixture-exclude-any <ctest --fixture-exclude-any>` on
the command line. This field supports macro expansion.
``setup``
-
An optional string specifying a regex for text fixtures to exclude
- from adding setup tests. Equivalent to ``--fixture-exclude-setup``
+ from adding setup tests. Equivalent to
+ :option:`--fixture-exclude-setup <ctest --fixture-exclude-setup>`
on the command line. This field supports macro expansion.
``cleanup``
-
An optional string specifying a regex for text fixtures to exclude
from adding cleanup tests. Equivalent to
- ``--fixture-exclude-cleanup`` on the command line. This field
- supports macro expansion.
+ :option:`--fixture-exclude-cleanup <ctest --fixture-exclude-cleanup>`
+ on the command line. This field supports macro expansion.
``execution``
-
An optional object specifying options for test execution. The object may
contain the following fields.
``stopOnFailure``
-
- An optional bool. If true, equivalent to passing ``--stop-on-failure``
- on the command line.
+ An optional bool. If true, equivalent to passing
+ :option:`--stop-on-failure <ctest --stop-on-failure>` on the command
+ line.
``enableFailover``
-
- An optional bool. If true, equivalent to passing ``-F`` on the command
- line.
+ An optional bool. If true, equivalent to passing :option:`-F <ctest -F>`
+ on the command line.
``jobs``
-
- An optional integer. Equivalent to passing ``--parallel`` on the
- command line.
+ An optional integer. Equivalent to passing
+ :option:`--parallel <ctest --parallel>` on the command line.
``resourceSpecFile``
-
- An optional string. Equivalent to passing ``--resource-spec-file`` on
+ An optional string. Equivalent to passing
+ :option:`--resource-spec-file <ctest --resource-spec-file>` on
the command line. This field supports macro expansion.
``testLoad``
-
- An optional integer. Equivalent to passing ``--test-load`` on the
- command line.
+ An optional integer. Equivalent to passing
+ :option:`--test-load <ctest --test-load>` on the command line.
``showOnly``
-
- An optional string. Equivalent to passing ``--show-only`` on the
+ An optional string. Equivalent to passing
+ :option:`--show-only <ctest --show-only>` on the
command line. The string must be one of the following values:
``human``
@@ -876,13 +792,11 @@ that may contain the following fields:
``json-v1``
``repeat``
-
An optional object specifying how to repeat tests. Equivalent to
- passing ``--repeat`` on the command line. The object must have the
- following fields.
+ passing :option:`--repeat <ctest --repeat>` on the command line.
+ The object must have the following fields.
``mode``
-
A required string. Must be one of the following values:
``until-fail``
@@ -892,42 +806,166 @@ that may contain the following fields:
``after-timeout``
``count``
-
A required integer.
``interactiveDebugging``
-
An optional bool. If true, equivalent to passing
- ``--interactive-debug-mode 1`` on the command line. If false,
- equivalent to passing ``--interactive-debug-mode 0`` on the command
- line.
+ :option:`--interactive-debug-mode 1 <ctest --interactive-debug-mode>`
+ on the command line. If false, equivalent to passing
+ :option:`--interactive-debug-mode 0 <ctest --interactive-debug-mode>`
+ on the command line.
``scheduleRandom``
-
- An optional bool. If true, equivalent to passing ``--schedule-random``
- on the command line.
+ An optional bool. If true, equivalent to passing
+ :option:`--schedule-random <ctest --schedule-random>` on the command
+ line.
``timeout``
-
- An optional integer. Equivalent to passing ``--timeout`` on the
- command line.
+ An optional integer. Equivalent to passing
+ :option:`--timeout <ctest --timeout>` on the command line.
``noTestsAction``
-
An optional string specifying the behavior if no tests are found. Must
be one of the following values:
``default``
-
Equivalent to not passing any value on the command line.
``error``
-
- Equivalent to passing ``--no-tests=error`` on the command line.
+ Equivalent to passing :option:`--no-tests=error <ctest --no-tests>`
+ on the command line.
``ignore``
+ Equivalent to passing :option:`--no-tests=ignore <ctest --no-tests>`
+ on the command line.
+
+Package Preset
+^^^^^^^^^^^^^^
+
+Package presets may be used in schema version ``6`` or above. Each entry of
+the ``packagePresets`` array is a JSON object that may contain the following
+fields:
+
+``name``
+ A required string representing the machine-friendly name of the preset.
+ This identifier is used in the :option:`cpack --preset` option.
+ There must not be two package presets in the union of ``CMakePresets.json``
+ and ``CMakeUserPresets.json`` in the same directory with the same name.
+ However, a package preset may have the same name as a configure, build, or
+ test preset.
+
+``hidden``
+ An optional boolean specifying whether or not a preset should be hidden.
+ If a preset is hidden, it cannot be used in the
+ :option:`--preset <cpack --preset>` argument
+ and does not have to have a valid ``configurePreset``, even from
+ inheritance. ``hidden`` presets are intended to be used as a base for
+ other presets to inherit via the ``inherits`` field.
+
+``inherits``
+ An optional array of strings representing the names of presets to inherit
+ from. This field can also be a string, which is equivalent to an array
+ containing one string.
- Equivalent to passing ``--no-tests=ignore`` on the command line.
+ The preset will inherit all of the fields from the
+ ``inherits`` presets by default (except ``name``, ``hidden``,
+ ``inherits``, ``description``, and ``displayName``), but can override
+ them as desired. If multiple ``inherits`` presets provide conflicting
+ values for the same field, the earlier preset in the ``inherits`` list
+ will be preferred.
+
+ A preset can only inherit from another preset that is defined in the
+ same file or in one of the files it includes (directly or indirectly).
+ Presets in ``CMakePresets.json`` may not inherit from presets in
+ ``CMakeUserPresets.json``.
+
+``condition``
+ An optional `Condition`_ object.
+
+``vendor``
+ An optional map containing vendor-specific information. CMake does not
+ interpret the contents of this field except to verify that it is a map
+ if it does exist. However, it should follow the same conventions as the
+ root-level ``vendor`` field. If vendors use their own per-preset
+ ``vendor`` field, they should implement inheritance in a sensible manner
+ when appropriate.
+
+``displayName``
+ An optional string with a human-friendly name of the preset.
+
+``description``
+ An optional string with a human-friendly description of the preset.
+
+``environment``
+ An optional map of environment variables. The key is the variable name
+ (which may not be an empty string), and the value is either ``null`` or
+ a string representing the value of the variable. Each variable is set
+ regardless of whether or not a value was given to it by the process's
+ environment. This field supports macro expansion, and environment
+ variables in this map may reference each other, and may be listed in any
+ order, as long as such references do not cause a cycle (for example, if
+ ``ENV_1`` is ``$env{ENV_2}``, ``ENV_2`` may not be ``$env{ENV_1}``.)
+
+ Environment variables are inherited through the ``inherits`` field, and
+ the preset's environment will be the union of its own ``environment``
+ and the ``environment`` from all its parents. If multiple presets in
+ this union define the same variable, the standard rules of ``inherits``
+ are applied. Setting a variable to ``null`` causes it to not be set,
+ even if a value was inherited from another preset.
+
+``configurePreset``
+ An optional string specifying the name of a configure preset to
+ associate with this package preset. If ``configurePreset`` is not
+ specified, it must be inherited from the inherits preset (unless this
+ preset is hidden). The build directory is inferred from the configure
+ preset, so packaging will run in the same ``binaryDir`` that the
+ configuration did and build did.
+
+``inheritConfigureEnvironment``
+ An optional boolean that defaults to true. If true, the environment
+ variables from the associated configure preset are inherited after all
+ inherited package preset environments, but before environment variables
+ explicitly specified in this package preset.
+
+``generators``
+ An optional list of strings representing generators for CPack to use.
+
+``configurations``
+ An optional list of strings representing build configurations for CPack to
+ package.
+
+``variables``
+ An optional map of variables to pass to CPack, equivalent to
+ :option:`-D <cpack -D>` arguments. Each key is the name of a variable, and
+ the value is the string to assign to that variable.
+
+``configFile``
+ An optional string representing the config file for CPack to use.
+
+``output``
+ An optional object specifying output options. Valid keys are:
+
+ ``debug``
+ An optional boolean specifying whether or not to print debug information.
+ A value of ``true`` is equivalent to passing
+ :option:`--debug <cpack --debug>` on the command line.
+
+ ``verbose``
+ An optional boolean specifying whether or not to print verbosely. A value
+ of ``true`` is equivalent to passing :option:`--verbose <cpack --verbose>`
+ on the command line.
+
+``packageName``
+ An optional string representing the package name.
+
+``packageVersion``
+ An optional string representing the package version.
+
+``packageDirectory``
+ An optional string representing the directory in which to place the package.
+
+``vendorName``
+ An optional string representing the vendor name.
Condition
^^^^^^^^^
@@ -943,65 +981,53 @@ a ``not``, ``anyOf``, or ``allOf`` condition) may not be ``null``. If it is an
object, it has the following fields:
``type``
-
A required string with one of the following values:
``"const"``
-
Indicates that the condition is constant. This is equivalent to using a
boolean in place of the object. The condition object will have the
following additional fields:
``value``
-
A required boolean which provides a constant value for the condition's
evaluation.
``"equals"``
``"notEquals"``
-
Indicates that the condition compares two strings to see if they are equal
(or not equal). The condition object will have the following additional
fields:
``lhs``
-
First string to compare. This field supports macro expansion.
``rhs``
-
Second string to compare. This field supports macro expansion.
``"inList"``
``"notInList"``
-
Indicates that the condition searches for a string in a list of strings.
The condition object will have the following additional fields:
``string``
-
A required string to search for. This field supports macro expansion.
``list``
-
A required list of strings to search. This field supports macro
expansion, and uses short-circuit evaluation.
``"matches"``
``"notMatches"``
-
Indicates that the condition searches for a regular expression in a string.
The condition object will have the following additional fields:
``string``
-
A required string to search. This field supports macro expansion.
``regex``
-
A required regular expression to search for. This field supports macro
expansion.
@@ -1013,17 +1039,14 @@ object, it has the following fields:
conditions. The condition object will have the following additional fields:
``conditions``
-
A required array of condition objects. These conditions use short-circuit
evaluation.
``"not"``
-
Indicates that the condition is an inversion of another condition. The
condition object will have the following additional fields:
``condition``
-
A required condition object.
Macro Expansion
@@ -1045,46 +1068,37 @@ interpreted as a literal dollar sign.
Recognized macros include:
``${sourceDir}``
-
Path to the project source directory (i.e. the same as
:variable:`CMAKE_SOURCE_DIR`).
``${sourceParentDir}``
-
Path to the project source directory's parent directory.
``${sourceDirName}``
-
The last filename component of ``${sourceDir}``. For example, if
``${sourceDir}`` is ``/path/to/source``, this would be ``source``.
``${presetName}``
-
Name specified in the preset's ``name`` field.
``${generator}``
-
Generator specified in the preset's ``generator`` field. For build and
test presets, this will evaluate to the generator specified by
``configurePreset``.
``${hostSystemName}``
-
The name of the host operating system. Contains the same value as
:variable:`CMAKE_HOST_SYSTEM_NAME`. This is allowed in preset files
specifying version ``3`` or above.
``${fileDir}``
-
Path to the directory containing the preset file which contains the macro.
This is allowed in preset files specifying version ``4`` or above.
``${dollar}``
-
A literal dollar sign (``$``).
``${pathListSep}``
-
Native character for separating lists of paths, such as ``:`` or ``;``.
For example, by setting ``PATH`` to
@@ -1095,7 +1109,6 @@ Recognized macros include:
This is allowed in preset files specifying version ``5`` or above.
``$env{<variable-name>}``
-
Environment variable with name ``<variable-name>``. The variable name may
not be an empty string. If the variable is defined in the ``environment``
field, that value is used instead of the value from the parent environment.
@@ -1108,7 +1121,6 @@ Recognized macros include:
the casing of environment variable names consistent.
``$penv{<variable-name>}``
-
Similar to ``$env{<variable-name>}``, except that the value only comes from
the parent environment, and never from the ``environment`` field. This
allows you to prepend or append values to existing environment variables.
@@ -1118,7 +1130,6 @@ Recognized macros include:
references.
``$vendor{<macro-name>}``
-
An extension point for vendors to insert their own macros. CMake will not
be able to use presets which have a ``$vendor{<macro-name>}`` macro, and
effectively ignores such presets. However, it will still be able to use
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index d88322c..d98f7cc 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -184,6 +184,16 @@ Properties on Targets
/prop_tgt/CUDA_STANDARD
/prop_tgt/CUDA_STANDARD_REQUIRED
/prop_tgt/CXX_EXTENSIONS
+ /prop_tgt/CXX_MODULE_DIRS
+ /prop_tgt/CXX_MODULE_DIRS_NAME
+ /prop_tgt/CXX_MODULE_SET
+ /prop_tgt/CXX_MODULE_SET_NAME
+ /prop_tgt/CXX_MODULE_SETS
+ /prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS
+ /prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS_NAME
+ /prop_tgt/CXX_MODULE_HEADER_UNIT_SET
+ /prop_tgt/CXX_MODULE_HEADER_UNIT_SET_NAME
+ /prop_tgt/CXX_MODULE_HEADER_UNIT_SETS
/prop_tgt/CXX_STANDARD
/prop_tgt/CXX_STANDARD_REQUIRED
/prop_tgt/DEBUG_POSTFIX
@@ -202,6 +212,7 @@ Properties on Targets
/prop_tgt/EXCLUDE_FROM_DEFAULT_BUILD_CONFIG
/prop_tgt/EXPORT_COMPILE_COMMANDS
/prop_tgt/EXPORT_NAME
+ /prop_tgt/EXPORT_NO_SYSTEM
/prop_tgt/EXPORT_PROPERTIES
/prop_tgt/FOLDER
/prop_tgt/Fortran_BUILDING_INSTRINSIC_MODULES
@@ -262,6 +273,8 @@ Properties on Targets
/prop_tgt/INTERFACE_COMPILE_DEFINITIONS
/prop_tgt/INTERFACE_COMPILE_FEATURES
/prop_tgt/INTERFACE_COMPILE_OPTIONS
+ /prop_tgt/INTERFACE_CXX_MODULE_SETS
+ /prop_tgt/INTERFACE_CXX_MODULE_HEADER_UNIT_SETS
/prop_tgt/INTERFACE_HEADER_SETS
/prop_tgt/INTERFACE_HEADER_SETS_TO_VERIFY
/prop_tgt/INTERFACE_INCLUDE_DIRECTORIES
@@ -375,6 +388,7 @@ Properties on Targets
/prop_tgt/Swift_LANGUAGE_VERSION
/prop_tgt/Swift_MODULE_DIRECTORY
/prop_tgt/Swift_MODULE_NAME
+ /prop_tgt/SYSTEM
/prop_tgt/TYPE
/prop_tgt/UNITY_BUILD
/prop_tgt/UNITY_BUILD_BATCH_SIZE
@@ -451,6 +465,7 @@ Properties on Targets
/prop_tgt/XCODE_SCHEME_ENVIRONMENT
/prop_tgt/XCODE_SCHEME_EXECUTABLE
/prop_tgt/XCODE_SCHEME_GUARD_MALLOC
+ /prop_tgt/XCODE_SCHEME_LAUNCH_MODE
/prop_tgt/XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
/prop_tgt/XCODE_SCHEME_MALLOC_GUARD_EDGES
/prop_tgt/XCODE_SCHEME_MALLOC_SCRIBBLE
@@ -459,6 +474,9 @@ Properties on Targets
/prop_tgt/XCODE_SCHEME_THREAD_SANITIZER_STOP
/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
/prop_tgt/XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
+ /prop_tgt/XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+ /prop_tgt/XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
+ /prop_tgt/XCODE_SCHEME_LAUNCH_CONFIGURATION
/prop_tgt/XCODE_SCHEME_WORKING_DIRECTORY
/prop_tgt/XCODE_SCHEME_ZOMBIE_OBJECTS
/prop_tgt/XCODE_XCCONFIG
diff --git a/Help/manual/cmake-toolchains.7.rst b/Help/manual/cmake-toolchains.7.rst
index e194df0..7fa73e7 100644
--- a/Help/manual/cmake-toolchains.7.rst
+++ b/Help/manual/cmake-toolchains.7.rst
@@ -96,7 +96,8 @@ Cross Compiling
===============
If :manual:`cmake(1)` is invoked with the command line parameter
-``--toolchain path/to/file`` or ``-DCMAKE_TOOLCHAIN_FILE=path/to/file``, the
+:option:`--toolchain path/to/file <cmake --toolchain>` or
+:option:`-DCMAKE_TOOLCHAIN_FILE=path/to/file <cmake -D>`, the
file will be loaded early to set values for the compilers.
The :variable:`CMAKE_CROSSCOMPILING` variable is set to true when CMake is
cross-compiling.
diff --git a/Help/manual/cmake-variables.7.rst b/Help/manual/cmake-variables.7.rst
index 7c8a7fa..ad6bfbc 100644
--- a/Help/manual/cmake-variables.7.rst
+++ b/Help/manual/cmake-variables.7.rst
@@ -278,6 +278,7 @@ Variables that Change Behavior
/variable/CMAKE_XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE
/variable/CMAKE_XCODE_SCHEME_ENVIRONMENT
/variable/CMAKE_XCODE_SCHEME_GUARD_MALLOC
+ /variable/CMAKE_XCODE_SCHEME_LAUNCH_MODE
/variable/CMAKE_XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP
/variable/CMAKE_XCODE_SCHEME_MALLOC_GUARD_EDGES
/variable/CMAKE_XCODE_SCHEME_MALLOC_SCRIBBLE
@@ -286,6 +287,9 @@ Variables that Change Behavior
/variable/CMAKE_XCODE_SCHEME_THREAD_SANITIZER_STOP
/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER
/variable/CMAKE_XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP
+ /variable/CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
+ /variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+ /variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
/variable/CMAKE_XCODE_SCHEME_WORKING_DIRECTORY
/variable/CMAKE_XCODE_SCHEME_ZOMBIE_OBJECTS
/variable/CMAKE_XCODE_XCCONFIG
@@ -300,6 +304,7 @@ Variables that Describe the System
/variable/ANDROID
/variable/APPLE
/variable/BORLAND
+ /variable/BSD
/variable/CMAKE_ANDROID_NDK_VERSION
/variable/CMAKE_CL_64
/variable/CMAKE_COMPILER_2005
@@ -319,8 +324,11 @@ Variables that Describe the System
/variable/CMAKE_SYSTEM_PROCESSOR
/variable/CMAKE_SYSTEM_VERSION
/variable/CYGWIN
+ /variable/DRAGONFLYBSD
+ /variable/FREEBSD
/variable/GHSMULTI
/variable/IOS
+ /variable/LINUX
/variable/MINGW
/variable/MSVC
/variable/MSVC10
@@ -336,6 +344,8 @@ Variables that Describe the System
/variable/MSVC_TOOLSET_VERSION
/variable/MSVC_VERSION
/variable/MSYS
+ /variable/NETBSD
+ /variable/OPENBSD
/variable/UNIX
/variable/WIN32
/variable/WINCE
diff --git a/Help/manual/cmake.1.rst b/Help/manual/cmake.1.rst
index 38105dd..98655e5 100644
--- a/Help/manual/cmake.1.rst
+++ b/Help/manual/cmake.1.rst
@@ -9,8 +9,7 @@ Synopsis
.. parsed-literal::
`Generate a Project Buildsystem`_
- cmake [<options>] <path-to-source>
- cmake [<options>] <path-to-existing-build>
+ cmake [<options>] <path-to-source | path-to-existing-build>
cmake [<options>] -S <path-to-source> -B <path-to-build>
`Build a Project`_
@@ -23,7 +22,7 @@ Synopsis
cmake --open <dir>
`Run a Script`_
- cmake [{-D <var>=<value>}...] -P <cmake-script-file>
+ cmake [-D <var>=<value>]... -P <cmake-script-file>
`Run a Command-Line Tool`_
cmake -E <command> [<options>]
@@ -96,9 +95,10 @@ Build Tree
Generator
This chooses the kind of buildsystem to generate. See the
:manual:`cmake-generators(7)` manual for documentation of all generators.
- Run ``cmake --help`` to see a list of generators available locally.
- Optionally use the ``-G`` option below to specify a generator, or simply
- accept the default CMake chooses for the current platform.
+ Run :option:`cmake --help` to see a list of generators available locally.
+ Optionally use the :option:`-G <cmake -G>` option below to specify a
+ generator, or simply accept the default CMake chooses for the current
+ platform.
When using one of the :ref:`Command-Line Build Tool Generators`
CMake expects that the environment needed by the compiler toolchain
@@ -152,11 +152,11 @@ source and build trees and generate a buildsystem:
In all cases the ``<options>`` may be zero or more of the `Options`_ below.
The above styles for specifying the source and build trees may be mixed.
-Paths specified with ``-S`` or ``-B`` are always classified as source or
-build trees, respectively. Paths specified with plain arguments are
-classified based on their content and the types of paths given earlier.
-If only one type of path is given, the current working directory (cwd)
-is used for the other. For example:
+Paths specified with :option:`-S <cmake -S>` or :option:`-B <cmake -B>`
+are always classified as source or build trees, respectively. Paths
+specified with plain arguments are classified based on their content
+and the types of paths given earlier. If only one type of path is given,
+the current working directory (cwd) is used for the other. For example:
============================== ============ ===========
Command Line Source Dir Build Dir
@@ -195,51 +195,60 @@ automatically choosing and invoking the appropriate native build tool.
Options
-------
+.. program:: cmake
+
.. include:: OPTIONS_BUILD.txt
-``--fresh``
+.. option:: --fresh
+
.. versionadded:: 3.24
Perform a fresh configuration of the build tree.
This removes any existing ``CMakeCache.txt`` file and associated
``CMakeFiles/`` directory, and recreates them from scratch.
-``-L[A][H]``
+.. option:: -L[A][H]
+
List non-advanced cached variables.
List ``CACHE`` variables will run CMake and list all the variables from
the CMake ``CACHE`` that are not marked as ``INTERNAL`` or :prop_cache:`ADVANCED`.
This will effectively display current CMake settings, which can then be
- changed with ``-D`` option. Changing some of the variables may result
- in more variables being created. If ``A`` is specified, then it will
- display also advanced variables. If ``H`` is specified, it will also
+ changed with :option:`-D <cmake -D>` option. Changing some of the variables
+ may result in more variables being created. If ``A`` is specified, then it
+ will display also advanced variables. If ``H`` is specified, it will also
display help for each variable.
-``-N``
+.. option:: -N
+
View mode only.
Only load the cache. Do not actually run configure and generate
steps.
-``--graphviz=[file]``
+.. option:: --graphviz=<file>
+
Generate graphviz of dependencies, see :module:`CMakeGraphVizOptions` for more.
Generate a graphviz input file that will contain all the library and
executable dependencies in the project. See the documentation for
:module:`CMakeGraphVizOptions` for more details.
-``--system-information [file]``
+.. option:: --system-information [file]
+
Dump information about this system.
Dump a wide range of information about the current system. If run
from the top of a binary tree for a CMake project it will dump
additional information such as the cache, log files etc.
-``--log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>``
- Set the log level.
+.. option:: --log-level=<level>
+
+ Set the log ``<level>``.
The :command:`message` command will only output messages of the specified
- log level or higher. The default log level is ``STATUS``.
+ log level or higher. The valid log levels are ``ERROR``, ``WARNING``,
+ ``NOTICE``, ``STATUS`` (default), ``VERBOSE``, ``DEBUG``, or ``TRACE``.
To make a log level persist between CMake runs, set
:variable:`CMAKE_MESSAGE_LOG_LEVEL` as a cache variable instead.
@@ -249,7 +258,12 @@ Options
For backward compatibility reasons, ``--loglevel`` is also accepted as a
synonym for this option.
-``--log-context``
+ .. versionadded:: 3.25
+ See the :command:`cmake_language` command for a way to
+ :ref:`query the current message logging level <query_message_log_level>`.
+
+.. option:: --log-context
+
Enable the :command:`message` command outputting context attached to each
message.
@@ -259,7 +273,8 @@ Options
When this command line option is given, :variable:`CMAKE_MESSAGE_CONTEXT_SHOW`
is ignored.
-``--debug-trycompile``
+.. option:: --debug-trycompile
+
Do not delete the :command:`try_compile` build tree.
Only useful on one :command:`try_compile` at a time.
@@ -270,13 +285,15 @@ Options
fail incorrectly. This option is best used for one try-compile at a
time, and only when debugging.
-``--debug-output``
+.. option:: --debug-output
+
Put cmake in a debug mode.
Print extra information during the cmake run like stack traces with
:command:`message(SEND_ERROR)` calls.
-``--debug-find``
+.. option:: --debug-find
+
Put cmake find commands in a debug mode.
Print extra find call information during the cmake run to standard
@@ -284,32 +301,39 @@ Options
See also the :variable:`CMAKE_FIND_DEBUG_MODE` variable for debugging
a more local part of the project.
-``--debug-find-pkg=<pkg>[,...]``
+.. option:: --debug-find-pkg=<pkg>[,...]
+
Put cmake find commands in a debug mode when running under calls
to :command:`find_package(\<pkg\>) <find_package>`, where ``<pkg>``
is an entry in the given comma-separated list of case-sensitive package
names.
- Like ``--debug-find``, but limiting scope to the specified packages.
+ Like :option:`--debug-find <cmake --debug-find>`, but limiting scope
+ to the specified packages.
+
+.. option:: --debug-find-var=<var>[,...]
-``--debug-find-var=<var>[,...]``
Put cmake find commands in a debug mode when called with ``<var>``
as the result variable, where ``<var>`` is an entry in the given
comma-separated list.
- Like ``--debug-find``, but limiting scope to the specified variable names.
+ Like :option:`--debug-find <cmake --debug-find>`, but limiting scope
+ to the specified variable names.
+
+.. option:: --trace
-``--trace``
Put cmake in trace mode.
Print a trace of all calls made and from where.
-``--trace-expand``
+.. option:: --trace-expand
+
Put cmake in trace mode.
- Like ``--trace``, but with variables expanded.
+ Like :option:`--trace <cmake --trace>`, but with variables expanded.
+
+.. option:: --trace-format=<format>
-``--trace-format=<format>``
Put cmake in trace mode and sets the trace output format.
``<format>`` can be one of the following values.
@@ -395,46 +419,57 @@ Options
Indicates the version of the JSON format. The version has a
major and minor components following semantic version conventions.
-``--trace-source=<file>``
+.. option:: --trace-source=<file>
+
Put cmake in trace mode, but output only lines of a specified file.
Multiple options are allowed.
-``--trace-redirect=<file>``
+.. option:: --trace-redirect=<file>
+
Put cmake in trace mode and redirect trace output to a file instead of stderr.
-``--warn-uninitialized``
+.. option:: --warn-uninitialized
+
Warn about uninitialized values.
Print a warning when an uninitialized variable is used.
-``--warn-unused-vars``
+.. option:: --warn-unused-vars
+
Does nothing. In CMake versions 3.2 and below this enabled warnings about
unused variables. In CMake versions 3.3 through 3.18 the option was broken.
In CMake 3.19 and above the option has been removed.
-``--no-warn-unused-cli``
+.. option:: --no-warn-unused-cli
+
Don't warn about command line options.
Don't find variables that are declared on the command line, but not
used.
-``--check-system-vars``
+.. option:: --check-system-vars
+
Find problems with variable usage in system files.
Normally, unused and uninitialized variables are searched for only
in :variable:`CMAKE_SOURCE_DIR` and :variable:`CMAKE_BINARY_DIR`.
This flag tells CMake to warn about other files as well.
-``--compile-no-warning-as-error``
+.. option:: --compile-no-warning-as-error
+
Ignore target property :prop_tgt:`COMPILE_WARNING_AS_ERROR` and variable
:variable:`CMAKE_COMPILE_WARNING_AS_ERROR`, preventing warnings from being
treated as errors on compile.
-``--profiling-output=<path>``
- Used in conjunction with ``--profiling-format`` to output to a given path.
+.. option:: --profiling-output=<path>
+
+ Used in conjunction with
+ :option:`--profiling-format <cmake --profiling-format>` to output to a
+ given path.
+
+.. option:: --profiling-format=<file>
-``--profiling-format=<file>``
Enable the output of profiling data of CMake script in the given format.
This can aid performance analysis of CMake scripts executed. Third party
@@ -445,7 +480,8 @@ Options
about:tracing tab of Google Chrome or using a plugin for a tool like Trace
Compass.
-``--preset <preset>``, ``--preset=<preset>``
+.. option:: --preset <preset>, --preset=<preset>
+
Reads a :manual:`preset <cmake-presets(7)>` from
``<path-to-source>/CMakePresets.json`` and
``<path-to-source>/CMakeUserPresets.json``. The preset may specify the
@@ -461,9 +497,12 @@ Options
a variable called ``MYVAR`` to ``1``, but the user sets it to ``2`` with a
``-D`` argument, the value ``2`` is preferred.
-``--list-presets, --list-presets=<[configure | build | test | all]>``
- Lists the available presets. If no option is specified only configure presets
- will be listed. The current working directory must contain CMake preset files.
+.. option:: --list-presets[=<type>]
+
+ Lists the available presets of the specified ``<type>``. Valid values for
+ ``<type>`` are ``configure``, ``build``, ``test``, ``package``, or ``all``.
+ If ``<type>`` is omitted, ``configure`` is assumed. The current working
+ directory must contain CMake preset files.
.. _`Build Tool Mode`:
@@ -481,21 +520,25 @@ project binary tree:
This abstracts a native build tool's command-line interface with the
following options:
-``--build <dir>``
+.. option:: --build <dir>
+
Project binary directory to be built. This is required (unless a preset
is specified) and must be first.
-``--preset <preset>``, ``--preset=<preset>``
+.. option:: --preset <preset>, --preset=<preset>
+
Use a build preset to specify build options. The project binary directory
is inferred from the ``configurePreset`` key. The current working directory
must contain CMake preset files.
See :manual:`preset <cmake-presets(7)>` for more details.
-``--list-presets``
+.. option:: --list-presets
+
Lists the available build presets. The current working directory must
contain CMake preset files.
-``--parallel [<jobs>], -j [<jobs>]``
+.. option:: -j [<jobs>], --parallel [<jobs>]
+
The maximum number of concurrent processes to use when building.
If ``<jobs>`` is omitted the native build tool's default number is used.
@@ -505,24 +548,29 @@ following options:
Some native build tools always build in parallel. The use of ``<jobs>``
value of ``1`` can be used to limit to a single job.
-``--target <tgt>..., -t <tgt>...``
+.. option:: -t <tgt>..., --target <tgt>...
+
Build ``<tgt>`` instead of the default target. Multiple targets may be
given, separated by spaces.
-``--config <cfg>``
+.. option:: --config <cfg>
+
For multi-configuration tools, choose configuration ``<cfg>``.
-``--clean-first``
+.. option:: --clean-first
+
Build target ``clean`` first, then build.
- (To clean only, use ``--target clean``.)
+ (To clean only, use :option:`--target clean <cmake --target>`.)
+
+.. option:: --resolve-package-references=<value>
-``--resolve-package-references=<on|off|only>``
.. versionadded:: 3.23
Resolve remote package references from external package managers (e.g. NuGet)
- before build. When set to ``on`` (default), packages will be restored before
- building a target. When set to ``only``, the packages will be restored, but no
- build will be performed. When set to ``off``, no packages will be restored.
+ before build. When ``<value>`` is set to ``on`` (default), packages will be
+ restored before building a target. When ``<value>`` is set to ``only``, the
+ packages will be restored, but no build will be performed. When
+ ``<value>`` is set to ``off``, no packages will be restored.
If the target does not define any package references, this option does nothing.
@@ -539,10 +587,12 @@ following options:
are restored using NuGet. It can be disabled by setting the
``CMAKE_VS_NUGET_PACKAGE_RESTORE`` variable to ``OFF``.
-``--use-stderr``
+.. option:: --use-stderr
+
Ignored. Behavior is default in CMake >= 3.0.
-``--verbose, -v``
+.. option:: -v, --verbose
+
Enable verbose output - if supported - including the build commands to be
executed.
@@ -550,10 +600,11 @@ following options:
:variable:`CMAKE_VERBOSE_MAKEFILE` cached variable is set.
-``--``
+.. option:: --
+
Pass remaining options to the native tool.
-Run ``cmake --build`` with no options for quick help.
+Run :option:`cmake --build` with no options for quick help.
Install a Project
=================
@@ -569,30 +620,37 @@ This may be used after building a project to run installation without
using the generated build system or the native build tool.
The options are:
-``--install <dir>``
+.. option:: --install <dir>
+
Project binary directory to install. This is required and must be first.
-``--config <cfg>``
+.. option:: --config <cfg>
+
For multi-configuration generators, choose configuration ``<cfg>``.
-``--component <comp>``
+.. option:: --component <comp>
+
Component-based install. Only install component ``<comp>``.
-``--default-directory-permissions <permissions>``
+.. option:: --default-directory-permissions <permissions>
+
Default directory install permissions. Permissions in format ``<u=rwx,g=rx,o=rx>``.
-``--prefix <prefix>``
+.. option:: --prefix <prefix>
+
Override the installation prefix, :variable:`CMAKE_INSTALL_PREFIX`.
-``--strip``
+.. option:: --strip
+
Strip before installing.
-``-v, --verbose``
+.. option:: -v, --verbose
+
Enable verbose output.
This option can be omitted if :envvar:`VERBOSE` environment variable is set.
-Run ``cmake --install`` with no options for quick help.
+Run :option:`cmake --install` with no options for quick help.
Open a Project
==============
@@ -610,14 +668,22 @@ supported by some generators.
Run a Script
============
+.. program:: cmake_P
+
.. code-block:: shell
- cmake [{-D <var>=<value>}...] -P <cmake-script-file> [-- <unparsed-options>...]
+ cmake [-D <var>=<value>]... -P <cmake-script-file> [-- <unparsed-options>...]
+
+.. option:: -D <var>=<value>
+
+ Define a variable for script mode.
-Process the given cmake file as a script written in the CMake
-language. No configure or generate step is performed and the cache
-is not modified. If variables are defined using ``-D``, this must be
-done before the ``-P`` argument.
+.. option:: -P <cmake-script-file>
+
+ Process the given cmake file as a script written in the CMake
+ language. No configure or generate step is performed and the cache
+ is not modified. If variables are defined using ``-D``, this must be
+ done before the ``-P`` argument.
Any options after ``--`` are not parsed by CMake, but they are still included
in the set of :variable:`CMAKE_ARGV<n> <CMAKE_ARGV0>` variables passed to the
@@ -629,16 +695,22 @@ script (including the ``--`` itself).
Run a Command-Line Tool
=======================
+.. program:: cmake_E
+
CMake provides builtin command-line tools through the signature
.. code-block:: shell
cmake -E <command> [<options>]
-Run ``cmake -E`` or ``cmake -E help`` for a summary of commands.
+.. option:: -E [help]
+
+ Run ``cmake -E`` or ``cmake -E help`` for a summary of commands.
+
Available commands are:
-``capabilities``
+.. option:: capabilities
+
.. versionadded:: 3.7
Report cmake capabilities in JSON format. The output is a JSON object
@@ -648,7 +720,7 @@ Available commands are:
A JSON object with version information. Keys are:
``string``
- The full version string as displayed by cmake ``--version``.
+ The full version string as displayed by cmake :option:`--version <cmake --version>`.
``major``
The major version number in integer form.
``minor``
@@ -675,7 +747,8 @@ Available commands are:
Optional member that may be present when the generator supports
platform specification via :variable:`CMAKE_GENERATOR_PLATFORM`
- (``-A ...``). The value is a list of platforms known to be supported.
+ (:option:`-A ... <cmake -A>`). The value is a list of platforms known to
+ be supported.
``extraGenerators``
A list of strings with all the extra generators compatible with
the generator.
@@ -700,7 +773,13 @@ Available commands are:
``true`` if cmake supports server-mode and ``false`` otherwise.
Always false since CMake 3.20.
-``cat [--] <files>...``
+ ``tls``
+ .. versionadded:: 3.25
+
+ ``true`` if TLS support is enabled and ``false`` otherwise.
+
+.. option:: cat [--] <files>...
+
.. versionadded:: 3.18
Concatenate files and print on the standard output.
@@ -711,10 +790,12 @@ Available commands are:
``-`` will result in an error. Use ``--`` to indicate the end of options, in
case a file starts with ``-``.
-``chdir <dir> <cmd> [<arg>...]``
+.. option:: chdir <dir> <cmd> [<arg>...]
+
Change the current working directory and run a command.
-``compare_files [--ignore-eol] <file1> <file2>``
+.. option:: compare_files [--ignore-eol] <file1> <file2>
+
Check if ``<file1>`` is same as ``<file2>``. If files are the same,
then returns ``0``, if not it returns ``1``. In case of invalid
arguments, it returns 2.
@@ -723,7 +804,8 @@ Available commands are:
The ``--ignore-eol`` option implies line-wise comparison and ignores
LF/CRLF differences.
-``copy <file>... <destination>``
+.. option:: copy <file>... <destination>
+
Copy files to ``<destination>`` (either file or directory).
If multiple files are specified, the ``<destination>`` must be
directory and it must exist. Wildcards are not supported.
@@ -733,7 +815,8 @@ Available commands are:
.. versionadded:: 3.5
Support for multiple input files.
-``copy_directory <dir>... <destination>``
+.. option:: copy_directory <dir>... <destination>
+
Copy content of ``<dir>...`` directories to ``<destination>`` directory.
If ``<destination>`` directory does not exist it will be created.
``copy_directory`` does follow symlinks.
@@ -745,7 +828,8 @@ Available commands are:
The command now fails when the source directory does not exist.
Previously it succeeded by creating an empty destination directory.
-``copy_if_different <file>... <destination>``
+.. option:: copy_if_different <file>... <destination>
+
Copy files to ``<destination>`` (either file or directory) if
they have changed.
If multiple files are specified, the ``<destination>`` must be
@@ -755,7 +839,8 @@ Available commands are:
.. versionadded:: 3.5
Support for multiple input files.
-``create_symlink <old> <new>``
+.. option:: create_symlink <old> <new>
+
Create a symbolic link ``<new>`` naming ``<old>``.
.. versionadded:: 3.13
@@ -764,7 +849,8 @@ Available commands are:
.. note::
Path to where ``<new>`` symbolic link will be created has to exist beforehand.
-``create_hardlink <old> <new>``
+.. option:: create_hardlink <old> <new>
+
.. versionadded:: 3.19
Create a hard link ``<new>`` naming ``<old>``.
@@ -773,31 +859,55 @@ Available commands are:
Path to where ``<new>`` hard link will be created has to exist beforehand.
``<old>`` has to exist beforehand.
-``echo [<string>...]``
+.. option:: echo [<string>...]
+
Displays arguments as text.
-``echo_append [<string>...]``
+.. option:: echo_append [<string>...]
+
Displays arguments as text but no new line.
-``env [--unset=NAME ...] [NAME=VALUE ...] [--] <command> [<arg>...]``
+.. option:: env [<options>] [--] <command> [<arg>...]
+
.. versionadded:: 3.1
- Run command in a modified environment.
+ Run command in a modified environment. Options are:
+
+ ``NAME=VALUE``
+ Replaces the current value of ``NAME`` with ``VALUE``.
+
+ ``--unset=NAME``
+ Unsets the current value of ``NAME``.
+
+ ``--modify ENVIRONMENT_MODIFICATION``
+ .. versionadded:: 3.25
+
+ Apply a single :prop_test:`ENVIRONMENT_MODIFICATION` operation to the
+ modified environment.
+
+ The ``NAME=VALUE`` and ``--unset=NAME`` options are equivalent to
+ ``--modify NAME=set:VALUE`` and ``--modify NAME=unset:``, respectively.
+ Note that ``--modify NAME=reset:`` resets ``NAME`` to the value it had
+ when ``cmake`` launched (or unsets it), not to the most recent
+ ``NAME=VALUE`` option.
.. versionadded:: 3.24
Added support for the double dash argument ``--``. Use ``--`` to stop
interpreting options/environment variables and treat the next argument as
the command, even if it start with ``-`` or contains a ``=``.
-``environment``
+.. option:: environment
+
Display the current environment variables.
-``false``
+.. option:: false
+
.. versionadded:: 3.16
Do nothing, with an exit code of 1.
-``make_directory <dir>...``
+.. option:: make_directory <dir>...
+
Create ``<dir>`` directories. If necessary, create parent
directories too. If a directory already exists it will be
silently ignored.
@@ -805,13 +915,15 @@ Available commands are:
.. versionadded:: 3.5
Support for multiple input directories.
-``md5sum <file>...``
+.. option:: md5sum <file>...
+
Create MD5 checksum of files in ``md5sum`` compatible format::
351abe79cd3800b38cdfb25d45015a15 file1.txt
052f86c15bbde68af55c7f7b340ab639 file2.txt
-``sha1sum <file>...``
+.. option:: sha1sum <file>...
+
.. versionadded:: 3.10
Create SHA1 checksum of files in ``sha1sum`` compatible format::
@@ -819,7 +931,8 @@ Available commands are:
4bb7932a29e6f73c97bb9272f2bdc393122f86e0 file1.txt
1df4c8f318665f9a5f2ed38f55adadb7ef9f559c file2.txt
-``sha224sum <file>...``
+.. option:: sha224sum <file>...
+
.. versionadded:: 3.10
Create SHA224 checksum of files in ``sha224sum`` compatible format::
@@ -827,7 +940,8 @@ Available commands are:
b9b9346bc8437bbda630b0b7ddfc5ea9ca157546dbbf4c613192f930 file1.txt
6dfbe55f4d2edc5fe5c9197bca51ceaaf824e48eba0cc453088aee24 file2.txt
-``sha256sum <file>...``
+.. option:: sha256sum <file>...
+
.. versionadded:: 3.10
Create SHA256 checksum of files in ``sha256sum`` compatible format::
@@ -835,7 +949,8 @@ Available commands are:
76713b23615d31680afeb0e9efe94d47d3d4229191198bb46d7485f9cb191acc file1.txt
15b682ead6c12dedb1baf91231e1e89cfc7974b3787c1e2e01b986bffadae0ea file2.txt
-``sha384sum <file>...``
+.. option:: sha384sum <file>...
+
.. versionadded:: 3.10
Create SHA384 checksum of files in ``sha384sum`` compatible format::
@@ -843,7 +958,8 @@ Available commands are:
acc049fedc091a22f5f2ce39a43b9057fd93c910e9afd76a6411a28a8f2b8a12c73d7129e292f94fc0329c309df49434 file1.txt
668ddeb108710d271ee21c0f3acbd6a7517e2b78f9181c6a2ff3b8943af92b0195dcb7cce48aa3e17893173c0a39e23d file2.txt
-``sha512sum <file>...``
+.. option:: sha512sum <file>...
+
.. versionadded:: 3.10
Create SHA512 checksum of files in ``sha512sum`` compatible format::
@@ -851,7 +967,8 @@ Available commands are:
2a78d7a6c5328cfb1467c63beac8ff21794213901eaadafd48e7800289afbc08e5fb3e86aa31116c945ee3d7bf2a6194489ec6101051083d1108defc8e1dba89 file1.txt
7a0b54896fe5e70cca6dd643ad6f672614b189bf26f8153061c4d219474b05dad08c4e729af9f4b009f1a1a280cb625454bf587c690f4617c27e3aebdf3b7a2d file2.txt
-``remove [-f] <file>...``
+.. option:: remove [-f] <file>...
+
.. deprecated:: 3.17
Remove the file(s). The planned behavior was that if any of the
@@ -864,7 +981,8 @@ Available commands are:
The implementation was buggy and always returned 0. It cannot be fixed without
breaking backwards compatibility. Use ``rm`` instead.
-``remove_directory <dir>...``
+.. option:: remove_directory <dir>...
+
.. deprecated:: 3.17
Remove ``<dir>`` directories and their contents. If a directory does
@@ -877,11 +995,13 @@ Available commands are:
.. versionadded:: 3.16
If ``<dir>`` is a symlink to a directory, just the symlink will be removed.
-``rename <oldname> <newname>``
+.. option:: rename <oldname> <newname>
+
Rename a file or directory (on one volume). If file with the ``<newname>`` name
already exists, then it will be silently replaced.
-``rm [-rRf] [--] <file|dir>...``
+.. option:: rm [-rRf] [--] <file|dir>...
+
.. versionadded:: 3.17
Remove the files ``<file>`` or directories ``<dir>``.
@@ -892,15 +1012,18 @@ Available commands are:
situations instead. Use ``--`` to stop interpreting options and treat all
remaining arguments as paths, even if they start with ``-``.
-``server``
+.. option:: server
+
Launch :manual:`cmake-server(7)` mode.
-``sleep <number>...``
+.. option:: sleep <number>...
+
.. versionadded:: 3.0
Sleep for given number of seconds.
-``tar [cxt][vf][zjJ] file.tar [<options>] [--] [<pathname>...]``
+.. option:: tar [cxt][vf][zjJ] file.tar [<options>] [--] [<pathname>...]
+
Create or extract a tar or zip archive. Options are:
``c``
@@ -983,7 +1106,8 @@ Available commands are:
``tar`` tool. The command now also parses all flags, and if an invalid flag
was provided, a warning is issued.
-``time <command> [<args>...]``
+.. option:: time <command> [<args>...]
+
Run command and display elapsed time.
.. versionadded:: 3.5
@@ -991,15 +1115,18 @@ Available commands are:
through to the child process. This may break scripts that worked around the
bug with their own extra quoting or escaping.
-``touch <file>...``
+.. option:: touch <file>...
+
Creates ``<file>`` if file do not exist.
If ``<file>`` exists, it is changing ``<file>`` access and modification times.
-``touch_nocreate <file>...``
+.. option:: touch_nocreate <file>...
+
Touch a file if it exists but do not create it. If a file does
not exist it will be silently ignored.
-``true``
+.. option:: true
+
.. versionadded:: 3.16
Do nothing, with an exit code of 0.
@@ -1009,22 +1136,26 @@ Windows-specific Command-Line Tools
The following ``cmake -E`` commands are available only on Windows:
-``delete_regv <key>``
+.. option:: delete_regv <key>
+
Delete Windows registry value.
-``env_vs8_wince <sdkname>``
+.. option:: env_vs8_wince <sdkname>
+
.. versionadded:: 3.2
Displays a batch file which sets the environment for the provided
Windows CE SDK installed in VS2005.
-``env_vs9_wince <sdkname>``
+.. option:: env_vs9_wince <sdkname>
+
.. versionadded:: 3.2
Displays a batch file which sets the environment for the provided
Windows CE SDK installed in VS2008.
-``write_regv <key> <value>``
+.. option:: write_regv <key> <value>
+
Write Windows registry value.
@@ -1058,6 +1189,8 @@ To print selected pages from the CMake documentation, use
with one of the following options:
+.. program:: cmake
+
.. include:: OPTIONS_HELP.txt
To view the presets available for a project, use
diff --git a/Help/manual/cpack.1.rst b/Help/manual/cpack.1.rst
index 395cd41..3f26d72 100644
--- a/Help/manual/cpack.1.rst
+++ b/Help/manual/cpack.1.rst
@@ -26,12 +26,12 @@ All supported generators are specified in the :manual:`cpack-generators
<cpack-generators(7)>` manual. The command ``cpack --help`` prints a
list of generators supported for the target platform. Which of them are
to be used can be selected through the :variable:`CPACK_GENERATOR` variable
-or through the command-line option ``-G``.
+or through the command-line option :option:`-G <cpack -G>`.
The **cpack** program is steered by a configuration file written in the
:manual:`CMake language <cmake-language(7)>`. Unless chosen differently
-through the command-line option ``--config``, the file ``CPackConfig.cmake``
-in the current directory is used.
+through the command-line option :option:`--config <cpack --config>`, the
+file ``CPackConfig.cmake`` in the current directory is used.
In the standard CMake workflow, the file ``CPackConfig.cmake`` is generated
by the :manual:`cmake <cmake(1)>` executable, provided the :module:`CPack`
@@ -40,7 +40,10 @@ module is included by the project's ``CMakeLists.txt`` file.
Options
=======
-``-G <generators>``
+.. program:: cpack
+
+.. option:: -G <generators>
+
``<generators>`` is a :ref:`semicolon-separated list <CMake Language Lists>`
of generator names. ``cpack`` will iterate through this list and produce
package(s) in that generator's format according to the details provided in
@@ -48,7 +51,8 @@ Options
the :variable:`CPACK_GENERATOR` variable determines the default set of
generators that will be used.
-``-C <configs>``
+.. option:: -C <configs>
+
Specify the project configuration(s) to be packaged (e.g. ``Debug``,
``Release``, etc.), where ``<configs>`` is a
:ref:`semicolon-separated list <CMake Language Lists>`.
@@ -58,36 +62,44 @@ Options
The user is responsible for ensuring that the configuration(s) listed
have already been built before invoking ``cpack``.
-``-D <var>=<value>``
+.. option:: -D <var>=<value>
+
Set a CPack variable. This will override any value set for ``<var>`` in the
input file read by ``cpack``.
-``--config <configFile>``
+.. option:: --config <configFile>
+
Specify the configuration file read by ``cpack`` to provide the packaging
details. By default, ``CPackConfig.cmake`` in the current directory will
be used.
-``--verbose, -V``
+.. option:: -V, --verbose
+
Run ``cpack`` with verbose output. This can be used to show more details
from the package generation tools and is suitable for project developers.
-``--debug``
+.. option:: --debug
+
Run ``cpack`` with debug output. This option is intended mainly for the
developers of ``cpack`` itself and is not normally needed by project
developers.
-``--trace``
+.. option:: --trace
+
Put the underlying cmake scripts in trace mode.
-``--trace-expand``
+.. option:: --trace-expand
+
Put the underlying cmake scripts in expanded trace mode.
-``-P <packageName>``
+.. option:: -P <packageName>
+
Override/define the value of the :variable:`CPACK_PACKAGE_NAME` variable used
for packaging. Any value set for this variable in the ``CPackConfig.cmake``
file will then be ignored.
-``-R <packageVersion>``
+.. option:: -R <packageVersion>
+
Override/define the value of the :variable:`CPACK_PACKAGE_VERSION`
variable used for packaging. It will override a value set in the
``CPackConfig.cmake`` file or one automatically computed from
@@ -95,16 +107,26 @@ Options
:variable:`CPACK_PACKAGE_VERSION_MINOR` and
:variable:`CPACK_PACKAGE_VERSION_PATCH`.
-``-B <packageDirectory>``
+.. option:: -B <packageDirectory>
+
Override/define :variable:`CPACK_PACKAGE_DIRECTORY`, which controls the
directory where CPack will perform its packaging work. The resultant
package(s) will be created at this location by default and a
``_CPack_Packages`` subdirectory will also be created below this directory to
use as a working area during package creation.
-``--vendor <vendorName>``
+.. option:: --vendor <vendorName>
+
Override/define :variable:`CPACK_PACKAGE_VENDOR`.
+.. option:: --preset <presetName>
+
+ Use a preset from :manual:`cmake-presets(7)`.
+
+.. option:: --list-presets
+
+ List presets from :manual:`cmake-presets(7)`.
+
.. include:: OPTIONS_HELP.txt
See Also
diff --git a/Help/manual/ctest.1.rst b/Help/manual/ctest.1.rst
index 06f0d4e..fe81a46 100644
--- a/Help/manual/ctest.1.rst
+++ b/Help/manual/ctest.1.rst
@@ -10,12 +10,24 @@ Synopsis
.. parsed-literal::
- ctest [<options>]
- ctest --build-and-test <path-to-source> <path-to-build>
- --build-generator <generator> [<options>...]
- [--build-options <opts>...] [--test-command <command> [<args>...]]
- ctest {-D <dashboard> | -M <model> -T <action> | -S <script> | -SP <script>}
- [-- <dashboard-options>...]
+ `Run Tests`_
+ ctest [<options>]
+
+ `Build and Test Mode`_
+ ctest --build-and-test <path-to-source> <path-to-build>
+ --build-generator <generator> [<options>...]
+ [--build-options <opts>...]
+ [--test-command <command> [<args>...]]
+
+ `Dashboard Client`_
+ ctest -D <dashboard> [-- <dashboard-options>...]
+ ctest -M <model> -T <action> [-- <dashboard-options>...]
+ ctest -S <script> [-- <dashboard-options>...]
+ ctest -SP <script> [-- <dashboard-options>...]
+
+ `View Help`_
+ ctest --help[-<topic>]
+
Description
===========
@@ -25,22 +37,27 @@ CMake-generated build trees created for projects that use the
:command:`enable_testing` and :command:`add_test` commands have testing support.
This program will run the tests and report results.
-.. _`CTest Options`:
+.. _`Run Tests`:
-Options
-=======
+Run Tests
+=========
+
+.. program:: ctest
+
+.. option:: --preset <preset>, --preset=<preset>
-``--preset <preset>``, ``--preset=<preset>``
Use a test preset to specify test options. The project binary directory
is inferred from the ``configurePreset`` key. The current working directory
must contain CMake preset files.
See :manual:`preset <cmake-presets(7)>` for more details.
-``--list-presets``
+.. option:: --list-presets
+
Lists the available test presets. The current working directory must contain
CMake preset files.
-``-C <cfg>, --build-config <cfg>``
+.. option:: -C <cfg>, --build-config <cfg>
+
Choose configuration to test.
Some CMake-generated build trees can have multiple build
@@ -48,7 +65,8 @@ Options
which one should be tested. Example configurations are ``Debug`` and
``Release``.
-``--progress``
+.. option:: --progress
+
Enable short progress output from tests.
When the output of **ctest** is being sent directly to a terminal, the
@@ -61,40 +79,47 @@ Options
This option can also be enabled by setting the environment variable
:envvar:`CTEST_PROGRESS_OUTPUT`.
-``-V,--verbose``
+.. option:: -V, --verbose
+
Enable verbose output from tests.
Test output is normally suppressed and only summary information is
displayed. This option will show all test output.
-``-VV,--extra-verbose``
+.. option:: -VV, --extra-verbose
+
Enable more verbose output from tests.
Test output is normally suppressed and only summary information is
displayed. This option will show even more test output.
-``--debug``
+.. option:: --debug
+
Displaying more verbose internals of CTest.
This feature will result in a large number of output that is mostly
useful for debugging dashboard problems.
-``--output-on-failure``
+.. option:: --output-on-failure
+
Output anything outputted by the test program if the test should fail.
This option can also be enabled by setting the
:envvar:`CTEST_OUTPUT_ON_FAILURE` environment variable
-``--stop-on-failure``
+.. option:: --stop-on-failure
+
Stop running the tests when the first failure happens.
-``-F``
+.. option:: -F
+
Enable failover.
This option allows CTest to resume a test set execution that was
previously interrupted. If no interruption occurred, the ``-F`` option
will have no effect.
-``-j <jobs>, --parallel <jobs>``
+.. option:: -j <jobs>, --parallel <jobs>
+
Run the tests in parallel using the given number of jobs.
This option tells CTest to run the tests in parallel using given
@@ -105,7 +130,8 @@ Options
See `Label and Subproject Summary`_.
-``--resource-spec-file <file>``
+.. option:: --resource-spec-file <file>
+
Run CTest with :ref:`resource allocation <ctest-resource-allocation>` enabled,
using the
:ref:`resource specification file <ctest-resource-specification-file>`
@@ -114,40 +140,48 @@ Options
When ``ctest`` is run as a `Dashboard Client`_ this sets the
``ResourceSpecFile`` option of the `CTest Test Step`_.
-``--test-load <level>``
- While running tests in parallel (e.g. with ``-j``), try not to start
- tests when they may cause the CPU load to pass above a given threshold.
+.. option:: --test-load <level>
+
+ While running tests in parallel (e.g. with :option:`-j <ctest -j>`), try
+ not to start tests when they may cause the CPU load to pass above a given
+ threshold.
When ``ctest`` is run as a `Dashboard Client`_ this sets the
``TestLoad`` option of the `CTest Test Step`_.
-``-Q,--quiet``
+.. option:: -Q, --quiet
+
Make CTest quiet.
This option will suppress all the output. The output log file will
- still be generated if the ``--output-log`` is specified. Options such
- as ``--verbose``, ``--extra-verbose``, and ``--debug`` are ignored
+ still be generated if the :option:`--output-log <ctest --output-log>` is
+ specified. Options such as :option:`--verbose <ctest --verbose>`,
+ :option:`--extra-verbose <ctest --extra-verbose>`, and
+ :option:`--debug <ctest --debug>` are ignored
if ``--quiet`` is specified.
-``-O <file>, --output-log <file>``
+.. option:: -O <file>, --output-log <file>
+
Output to log file.
This option tells CTest to write all its output to a ``<file>`` log file.
-``--output-junit <file>``
+.. option:: --output-junit <file>
+
Write test results in JUnit format.
This option tells CTest to write test results to ``<file>`` in JUnit XML
format. If ``<file>`` already exists, it will be overwritten. If using the
- ``-S`` option to run a dashboard script, use the ``OUTPUT_JUNIT`` keyword
- with the :command:`ctest_test` command instead.
+ :option:`-S <ctest -S>` option to run a dashboard script, use the
+ ``OUTPUT_JUNIT`` keyword with the :command:`ctest_test` command instead.
+
+.. option:: -N, --show-only[=<format>]
-``-N,--show-only[=<format>]``
Disable actual execution of tests.
This option tells CTest to list the tests that would be run but not
- actually run them. Useful in conjunction with the ``-R`` and ``-E``
- options.
+ actually run them. Useful in conjunction with the :option:`-R <ctest -R>`
+ and :option:`-E <ctest -E>` options.
``<format>`` can be one of the following values.
@@ -159,7 +193,8 @@ Options
Dump the test information in JSON format.
See `Show as JSON Object Model`_.
-``-L <regex>, --label-regex <regex>``
+.. option:: -L <regex>, --label-regex <regex>
+
Run tests with labels matching regular expression as described under
:ref:`string(REGEX) <Regex Specification>`.
@@ -169,19 +204,22 @@ Options
of the test's labels (i.e. the multiple ``-L`` labels form an ``AND``
relationship). See `Label Matching`_.
-``-R <regex>, --tests-regex <regex>``
+.. option:: -R <regex>, --tests-regex <regex>
+
Run tests matching regular expression.
This option tells CTest to run only the tests whose names match the
given regular expression.
-``-E <regex>, --exclude-regex <regex>``
+.. option:: -E <regex>, --exclude-regex <regex>
+
Exclude tests matching regular expression.
This option tells CTest to NOT run the tests whose names match the
given regular expression.
-``-LE <regex>, --label-exclude <regex>``
+.. option:: -LE <regex>, --label-exclude <regex>
+
Exclude tests with labels matching regular expression.
This option tells CTest to NOT run the tests whose labels match the
@@ -190,7 +228,8 @@ Options
of the test's labels (i.e. the multiple ``-LE`` labels form an ``AND``
relationship). See `Label Matching`_.
-``-FA <regex>, --fixture-exclude-any <regex>``
+.. option:: -FA <regex>, --fixture-exclude-any <regex>
+
Exclude fixtures matching ``<regex>`` from automatically adding any tests to
the test set.
@@ -201,72 +240,18 @@ Options
including test dependencies and skipping tests that have fixture setup tests
that fail.
-``-FS <regex>, --fixture-exclude-setup <regex>``
- Same as ``-FA`` except only matching setup tests are excluded.
-
-``-FC <regex>, --fixture-exclude-cleanup <regex>``
- Same as ``-FA`` except only matching cleanup tests are excluded.
-
-``-D <dashboard>, --dashboard <dashboard>``
- Execute dashboard test.
-
- This option tells CTest to act as a CDash client and perform a
- dashboard test. All tests are ``<Mode><Test>``, where ``<Mode>`` can be
- ``Experimental``, ``Nightly``, and ``Continuous``, and ``<Test>`` can be
- ``Start``, ``Update``, ``Configure``, ``Build``, ``Test``,
- ``Coverage``, and ``Submit``.
-
- See `Dashboard Client`_.
+.. option:: -FS <regex>, --fixture-exclude-setup <regex>
-``-D <var>:<type>=<value>``
- Define a variable for script mode.
-
- Pass in variable values on the command line. Use in conjunction
- with ``-S`` to pass variable values to a dashboard script. Parsing ``-D``
- arguments as variable values is only attempted if the value
- following ``-D`` does not match any of the known dashboard types.
-
-``-M <model>, --test-model <model>``
- Sets the model for a dashboard.
-
- This option tells CTest to act as a CDash client where the ``<model>``
- can be ``Experimental``, ``Nightly``, and ``Continuous``.
- Combining ``-M`` and ``-T`` is similar to ``-D``.
-
- See `Dashboard Client`_.
-
-``-T <action>, --test-action <action>``
- Sets the dashboard action to perform.
-
- This option tells CTest to act as a CDash client and perform some
- action such as ``start``, ``build``, ``test`` etc. See
- `Dashboard Client Steps`_ for the full list of actions.
- Combining ``-M`` and ``-T`` is similar to ``-D``.
-
- See `Dashboard Client`_.
-
-``-S <script>, --script <script>``
- Execute a dashboard for a configuration.
+ Same as :option:`-FA <ctest -FA>` except only matching setup tests are
+ excluded.
- This option tells CTest to load in a configuration script which sets
- a number of parameters such as the binary and source directories.
- Then CTest will do what is required to create and run a dashboard.
- This option basically sets up a dashboard and then runs ``ctest -D``
- with the appropriate options.
-
- See `Dashboard Client`_.
+.. option:: -FC <regex>, --fixture-exclude-cleanup <regex>
-``-SP <script>, --script-new-process <script>``
- Execute a dashboard for a configuration.
-
- This option does the same operations as ``-S`` but it will do them in a
- separate process. This is primarily useful in cases where the
- script may modify the environment and you do not want the modified
- environment to impact other ``-S`` scripts.
+ Same as :option:`-FA <ctest -FA>` except only matching cleanup tests are
+ excluded.
- See `Dashboard Client`_.
+.. option:: -I [Start,End,Stride,test#,test#|Test file], --tests-information
-``-I [Start,End,Stride,test#,test#|Test file], --tests-information``
Run a specific number of tests by number.
This option causes CTest to run tests starting at number ``Start``,
@@ -275,23 +260,29 @@ Options
``End``, or ``Stride`` can be empty. Optionally a file can be given that
contains the same syntax as the command line.
-``-U, --union``
- Take the Union of ``-I`` and ``-R``.
+.. option:: -U, --union
+
+ Take the Union of :option:`-I <ctest -I>` and :option:`-R <ctest -R>`.
- When both ``-R`` and ``-I`` are specified by default the intersection of
- tests are run. By specifying ``-U`` the union of tests is run instead.
+ When both :option:`-R <ctest -R>` and :option:`-I <ctest -I>` are specified
+ by default the intersection of tests are run. By specifying ``-U`` the union
+ of tests is run instead.
+
+.. option:: --rerun-failed
-``--rerun-failed``
Run only the tests that failed previously.
This option tells CTest to perform only the tests that failed during
its previous run. When this option is specified, CTest ignores all
- other options intended to modify the list of tests to run (``-L``, ``-R``,
- ``-E``, ``-LE``, ``-I``, etc). In the event that CTest runs and no tests
- fail, subsequent calls to CTest with the ``--rerun-failed`` option will run
- the set of tests that most recently failed (if any).
+ other options intended to modify the list of tests to run (
+ :option:`-L <ctest -L>`, :option:`-R <ctest -R>`, :option:`-E <ctest -E>`,
+ :option:`-LE <ctest -LE>`, :option:`-I <ctest -I>`, etc). In the event that
+ CTest runs and no tests fail, subsequent calls to CTest with the
+ ``--rerun-failed`` option will run the set of tests that most recently
+ failed (if any).
+
+.. option:: --repeat <mode>:<n>
-``--repeat <mode>:<n>``
Run tests repeatedly based on the given ``<mode>`` up to ``<n>`` times.
The modes are:
@@ -310,17 +301,20 @@ Options
This is useful in tolerating sporadic timeouts in test cases
on busy machines.
-``--repeat-until-fail <n>``
- Equivalent to ``--repeat until-fail:<n>``.
+.. option:: --repeat-until-fail <n>
+
+ Equivalent to :option:`--repeat until-fail:\<n\> <ctest --repeat>`.
+
+.. option:: --max-width <width>
-``--max-width <width>``
Set the max width for a test name to output.
Set the maximum width for each test name to show in the output.
This allows the user to widen the output to avoid clipping the test
name which can be very annoying.
-``--interactive-debug-mode [0|1]``
+.. option:: --interactive-debug-mode [0|1]
+
Set the interactive mode to ``0`` or ``1``.
This option causes CTest to run tests in either an interactive mode
@@ -332,7 +326,8 @@ Options
popup windows to appear. Now, due to CTest's use of ``libuv`` to launch
test processes, all system debug popup windows are always blocked.
-``--no-label-summary``
+.. option:: --no-label-summary
+
Disable timing summary information for labels.
This option tells CTest not to print summary information for each
@@ -341,7 +336,8 @@ Options
See `Label and Subproject Summary`_.
-``--no-subproject-summary``
+.. option:: --no-subproject-summary
+
Disable timing summary information for subprojects.
This option tells CTest not to print summary information for each
@@ -350,79 +346,95 @@ Options
See `Label and Subproject Summary`_.
-``--build-and-test``
-See `Build and Test Mode`_.
+.. option:: --test-dir <dir>
-``--test-dir <dir>``
-Specify the directory in which to look for tests.
+ Specify the directory in which to look for tests.
+
+.. option:: --test-output-size-passed <size>
-``--test-output-size-passed <size>``
.. versionadded:: 3.4
Limit the output for passed tests to ``<size>`` bytes.
-``--test-output-size-failed <size>``
+.. option:: --test-output-size-failed <size>
+
.. versionadded:: 3.4
Limit the output for failed tests to ``<size>`` bytes.
-``--test-output-truncation <mode>``
+.. option:: --test-output-truncation <mode>
+
.. versionadded:: 3.24
Truncate ``tail`` (default), ``middle`` or ``head`` of test output once
maximum output size is reached.
-``--overwrite``
+.. option:: --overwrite
+
Overwrite CTest configuration option.
By default CTest uses configuration options from configuration file.
This option will overwrite the configuration option.
-``--force-new-ctest-process``
+.. option:: --force-new-ctest-process
+
Run child CTest instances as new processes.
By default CTest will run child CTest instances within the same
process. If this behavior is not desired, this argument will
enforce new processes for child CTest processes.
-``--schedule-random``
+.. option:: --schedule-random
+
Use a random order for scheduling tests.
This option will run the tests in a random order. It is commonly
used to detect implicit dependencies in a test suite.
-``--submit-index``
+.. option:: --submit-index
+
Legacy option for old Dart2 dashboard server feature.
Do not use.
-``--timeout <seconds>``
+.. option:: --timeout <seconds>
+
Set the default test timeout.
This option effectively sets a timeout on all tests that do not
already have a timeout set on them via the :prop_test:`TIMEOUT`
property.
-``--stop-time <time>``
+.. option:: --stop-time <time>
+
Set a time at which all tests should stop running.
Set a real time of day at which all tests should timeout. Example:
``7:00:00 -0400``. Any time format understood by the curl date parser
is accepted. Local time is assumed if no timezone is specified.
-``--print-labels``
+.. option:: --print-labels
+
Print all available test labels.
This option will not run any tests, it will simply print the list of
all labels associated with the test set.
-``--no-tests=<[error|ignore]>``
- Regard no tests found either as error or ignore it.
+.. option:: --no-tests=<action>
+
+ Regard no tests found either as error (when ``<action>`` is set to
+ ``error``) or ignore it (when ``<action>`` is set to ``ignore``).
If no tests were found, the default behavior of CTest is to always log an
error message but to return an error code in script mode only. This option
unifies the behavior of CTest by either returning an error code if no tests
were found or by ignoring it.
+View Help
+=========
+
+To print version details or selected pages from the CMake documentation,
+use one of the following options:
+
.. include:: OPTIONS_HELP.txt
.. _`Label Matching`:
@@ -435,17 +447,17 @@ or excluded from a test run by filtering on the labels.
Each individual filter is a regular expression applied to
the labels attached to a test.
-When ``-L`` is used, in order for a test to be included in a
+When :option:`-L <ctest -L>` is used, in order for a test to be included in a
test run, each regular expression must match at least one
-label. Using more than one ``-L`` option means "match **all**
+label. Using more than one :option:`-L <ctest -L>` option means "match **all**
of these".
-The ``-LE`` option works just like ``-L``, but excludes tests
-rather than including them. A test is excluded if each regular
-expression matches at least one label.
+The :option:`-LE <ctest -LE>` option works just like :option:`-L <ctest -L>`,
+but excludes tests rather than including them. A test is excluded if each
+regular expression matches at least one label.
-If a test has no labels attached to it, then ``-L`` will never
-include that test, and ``-LE`` will never exclude that test.
+If a test has no labels attached to it, then :option:`-L <ctest -L>` will never
+include that test, and :option:`-LE <ctest -LE>` will never exclude that test.
As an example of tests with labels, consider five tests,
with the following labels:
@@ -532,62 +544,85 @@ be provided to use ``--build-and-test``. If ``--test-command`` is specified
then that will be run after the build is complete. Other options that affect
this mode include:
-``--build-target``
- Specify a specific target to build.
+.. option:: --build-and-test
+
+ Switch into the build and test mode.
- If left out the ``all`` target is built.
+.. option:: --build-target
+
+ Specify a specific target to build. The option can be given multiple times
+ with different targets, in which case each target is built in turn.
+ A clean will be done before building each target unless the
+ :option:`--build-noclean` option is given.
+
+ If no ``--build-target`` is specified, the ``all`` target is built.
+
+.. option:: --build-nocmake
-``--build-nocmake``
Run the build without running cmake first.
Skip the cmake step.
-``--build-run-dir``
+.. option:: --build-run-dir
+
Specify directory to run programs from.
Directory where programs will be after it has been compiled.
-``--build-two-config``
+.. option:: --build-two-config
+
Run CMake twice.
-``--build-exe-dir``
+.. option:: --build-exe-dir
+
Specify the directory for the executable.
-``--build-generator``
+.. option:: --build-generator
+
Specify the generator to use. See the :manual:`cmake-generators(7)` manual.
-``--build-generator-platform``
+.. option:: --build-generator-platform
+
Specify the generator-specific platform.
-``--build-generator-toolset``
+.. option:: --build-generator-toolset
+
Specify the generator-specific toolset.
-``--build-project``
+.. option:: --build-project
+
Specify the name of the project to build.
-``--build-makeprogram``
+.. option:: --build-makeprogram
+
Specify the explicit make program to be used by CMake when configuring and
building the project. Only applicable for Make and Ninja based generators.
-``--build-noclean``
+.. option:: --build-noclean
+
Skip the make clean step.
-``--build-config-sample``
+.. option:: --build-config-sample
+
A sample executable to use to determine the configuration that
should be used. e.g. ``Debug``, ``Release`` etc.
-``--build-options``
+.. option:: --build-options
+
Additional options for configuring the build (i.e. for CMake, not for
the build tool). Note that if this is specified, the ``--build-options``
keyword and its arguments must be the last option given on the command
line, with the possible exception of ``--test-command``.
-``--test-command``
- The command to run as the test step with the ``--build-and-test`` option.
+.. option:: --test-command
+
+ The command to run as the test step with the
+ :option:`--build-and-test <ctest --build-and-test>` option.
All arguments following this keyword will be assumed to be part of the
test command line, so it must be the last option given.
-``--test-timeout``
+.. option:: --test-timeout
+
The time limit in seconds
.. _`Dashboard Client`:
@@ -600,12 +635,80 @@ application. As a dashboard client, CTest performs a sequence of steps
to configure, build, and test software, and then submits the results to
a `CDash`_ server. The command-line signature used to submit to `CDash`_ is::
- ctest (-D <dashboard> | -M <model> -T <action> | -S <script> | -SP <script>)
- [-- <dashboard-options>...]
+ ctest -D <dashboard> [-- <dashboard-options>...]
+ ctest -M <model> -T <action> [-- <dashboard-options>...]
+ ctest -S <script> [-- <dashboard-options>...]
+ ctest -SP <script> [-- <dashboard-options>...]
Options for Dashboard Client include:
-``--group <group>``
+.. option:: -D <dashboard>, --dashboard <dashboard>
+
+ Execute dashboard test.
+
+ This option tells CTest to act as a CDash client and perform a
+ dashboard test. All tests are ``<Mode><Test>``, where ``<Mode>`` can be
+ ``Experimental``, ``Nightly``, and ``Continuous``, and ``<Test>`` can be
+ ``Start``, ``Update``, ``Configure``, ``Build``, ``Test``,
+ ``Coverage``, and ``Submit``.
+
+ If ``<dashboard>`` is not one of the recognized ``<Mode><Test>`` values,
+ this will be treated as a variable definition instead (see the
+ :ref:`dashboard-options <Dashboard Options>` further below).
+
+.. option:: -M <model>, --test-model <model>
+
+ Sets the model for a dashboard.
+
+ This option tells CTest to act as a CDash client where the ``<model>``
+ can be ``Experimental``, ``Nightly``, and ``Continuous``.
+ Combining ``-M`` and :option:`-T <ctest -T>` is similar to
+ :option:`-D <ctest -D>`.
+
+.. option:: -T <action>, --test-action <action>
+
+ Sets the dashboard action to perform.
+
+ This option tells CTest to act as a CDash client and perform some
+ action such as ``start``, ``build``, ``test`` etc. See
+ `Dashboard Client Steps`_ for the full list of actions.
+ Combining :option:`-M <ctest -M>` and ``-T`` is similar to
+ :option:`-D <ctest -D>`.
+
+.. option:: -S <script>, --script <script>
+
+ Execute a dashboard for a configuration.
+
+ This option tells CTest to load in a configuration script which sets
+ a number of parameters such as the binary and source directories.
+ Then CTest will do what is required to create and run a dashboard.
+ This option basically sets up a dashboard and then runs :option:`ctest -D`
+ with the appropriate options.
+
+.. option:: -SP <script>, --script-new-process <script>
+
+ Execute a dashboard for a configuration.
+
+ This option does the same operations as :option:`-S <ctest -S>` but it
+ will do them in a separate process. This is primarily useful in cases
+ where the script may modify the environment and you do not want the modified
+ environment to impact other :option:`-S <ctest -S>` scripts.
+
+.. _`Dashboard Options`:
+
+The available ``<dashboard-options>`` are the following:
+
+.. option:: -D <var>:<type>=<value>
+
+ Define a variable for script mode.
+
+ Pass in variable values on the command line. Use in conjunction
+ with :option:`-S <ctest -S>` to pass variable values to a dashboard script.
+ Parsing ``-D`` arguments as variable values is only attempted if the value
+ following ``-D`` does not match any of the known dashboard types.
+
+.. option:: --group <group>
+
Specify what group you'd like to submit results to
Submit dashboard to specified group instead of default one. By
@@ -616,29 +719,34 @@ Options for Dashboard Client include:
This replaces the deprecated option ``--track``.
Despite the name change its behavior is unchanged.
-``-A <file>, --add-notes <file>``
+.. option:: -A <file>, --add-notes <file>
+
Add a notes file with submission.
This option tells CTest to include a notes file when submitting
dashboard.
-``--tomorrow-tag``
+.. option:: --tomorrow-tag
+
``Nightly`` or ``Experimental`` starts with next day tag.
This is useful if the build will not finish in one day.
-``--extra-submit <file>[;<file>]``
+.. option:: --extra-submit <file>[;<file>]
+
Submit extra files to the dashboard.
This option will submit extra files to the dashboard.
-``--http1.0``
+.. option:: --http1.0
+
Submit using `HTTP 1.0`.
This option will force CTest to use `HTTP 1.0` to submit files to the
dashboard, instead of `HTTP 1.1`.
-``--no-compress-output``
+.. option:: --no-compress-output
+
Do not compress test output when submitting.
This flag will turn off automatic compression of test output. Use
@@ -722,7 +830,7 @@ Run the ``ctest`` command with the current working directory set
to the build tree and use one of these signatures::
ctest -D <mode>[<step>]
- ctest -M <mode> [ -T <step> ]...
+ ctest -M <mode> [-T <step>]...
The ``<mode>`` must be one of the above `Dashboard Client Modes`_,
and each ``<step>`` must be one of the above `Dashboard Client Steps`_.
@@ -1027,9 +1135,9 @@ Configuration settings include:
``DefaultCTestConfigurationType``
When the build system to be launched allows build-time selection
of the configuration (e.g. ``Debug``, ``Release``), this specifies
- the default configuration to be built when no ``-C`` option is
- given to the ``ctest`` command. The value will be substituted into
- the value of ``MakeCommand`` to replace the literal string
+ the default configuration to be built when no :option:`-C <ctest -C>`
+ option is given to the ``ctest`` command. The value will be substituted
+ into the value of ``MakeCommand`` to replace the literal string
``${CTEST_CONFIGURATION_TYPE}`` if it appears.
* `CTest Script`_ variable: :variable:`CTEST_CONFIGURATION_TYPE`
@@ -1101,8 +1209,9 @@ Configuration settings include:
See `Label and Subproject Summary`_.
``TestLoad``
- While running tests in parallel (e.g. with ``-j``), try not to start
- tests when they may cause the CPU load to pass above a given threshold.
+ While running tests in parallel (e.g. with :option:`-j <ctest -j>`),
+ try not to start tests when they may cause the CPU load to pass above
+ a given threshold.
* `CTest Script`_ variable: :variable:`CTEST_TEST_LOAD`
* :module:`CTest` module variable: ``CTEST_TEST_LOAD``
diff --git a/Help/manual/presets/schema.json b/Help/manual/presets/schema.json
index c96405c..f3a7532 100644
--- a/Help/manual/presets/schema.json
+++ b/Help/manual/presets/schema.json
@@ -72,6 +72,22 @@
"include": { "$ref": "#/definitions/include"}
},
"additionalProperties": false
+ },
+ {
+ "properties": {
+ "version": {
+ "const": 6,
+ "description": "A required integer representing the version of the JSON schema."
+ },
+ "cmakeMinimumRequired": { "$ref": "#/definitions/cmakeMinimumRequired"},
+ "vendor": { "$ref": "#/definitions/vendor" },
+ "configurePresets": { "$ref": "#/definitions/configurePresetsV3"},
+ "buildPresets": { "$ref": "#/definitions/buildPresetsV4"},
+ "testPresets": { "$ref": "#/definitions/testPresetsV5"},
+ "packagePresets": { "$ref": "#/definitions/packagePresetsV6"},
+ "include": { "$ref": "#/definitions/include"}
+ },
+ "additionalProperties": false
}
],
"required": [
@@ -476,12 +492,12 @@
"properties": {
"name": {
"type": "string",
- "description": "A required string representing the machine-friendly name of the preset. This identifier is used in the --preset argument. There must not be two presets (configure, build, or test) in the union of CMakePresets.json and CMakeUserPresets.json in the same directory with the same name.",
+ "description": "A required string representing the machine-friendly name of the preset. This identifier is used in the --preset argument. There must not be two presets (configure, build, test, or package) in the union of CMakePresets.json and CMakeUserPresets.json in the same directory with the same name.",
"minLength": 1
},
"hidden": {
"type": "boolean",
- "description": "An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the --preset argument, will not show up in the CMake GUI, and does not have to have a valid configurePreset, even from inheritance. Hidden presets are intended to be used as a base for other presets to inherit via the inherits field."
+ "description": "An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the --preset argument and does not have to have a valid configurePreset, even from inheritance. Hidden presets are intended to be used as a base for other presets to inherit via the inherits field."
},
"inherits": {
"anyOf": [
@@ -728,12 +744,12 @@
"properties": {
"name": {
"type": "string",
- "description": "A required string representing the machine-friendly name of the preset. This identifier is used in the --preset argument. There must not be two presets (configure, build, or test) in the union of CMakePresets.json and CMakeUserPresets.json in the same directory with the same name.",
+ "description": "A required string representing the machine-friendly name of the preset. This identifier is used in the --preset argument. There must not be two presets (configure, build, test, or package) in the union of CMakePresets.json and CMakeUserPresets.json in the same directory with the same name.",
"minLength": 1
},
"hidden": {
"type": "boolean",
- "description": "An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the --preset argument, will not show up in the CMake GUI, and does not have to have a valid configurePreset, even from inheritance. Hidden presets are intended to be used as a base for other presets to inherit via the inherits field."
+ "description": "An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the --preset argument and does not have to have a valid configurePreset, even from inheritance. Hidden presets are intended to be used as a base for other presets to inherit via the inherits field."
},
"inherits": {
"anyOf": [
@@ -1129,6 +1145,182 @@
"additionalProperties": false
}
},
+ "packagePresetsItemsV6": {
+ "type": "array",
+ "description": "An optional array of package preset objects. Used to specify arguments to cpack. Available in version 6 and higher.",
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "description": "A required string representing the machine-friendly name of the preset. This identifier is used in the --preset argument. There must not be two presets (configure, build, test, or package) in the union of CMakePresets.json and CMakeUserPresets.json in the same directory with the same name.",
+ "minLength": 1
+ },
+ "hidden": {
+ "type": "boolean",
+ "description": "An optional boolean specifying whether or not a preset should be hidden. If a preset is hidden, it cannot be used in the --preset argument and does not have to have a valid configurePreset, even from inheritance. Hidden presets are intended to be used as a base for other presets to inherit via the inherits field."
+ },
+ "inherits": {
+ "anyOf": [
+ {
+ "type": "string",
+ "description": "An optional string representing the name of the package preset to inherit from.",
+ "minLength": 1
+ },
+ {
+ "type": "array",
+ "description": "An optional array of strings representing the names of package presets to inherit from. The preset will inherit all of the fields from the inherits presets by default (except name, hidden, inherits, description, and displayName), but can override them as desired. If multiple inherits presets provide conflicting values for the same field, the earlier preset in the inherits list will be preferred. Presets in CMakePresets.json must not inherit from presets in CMakeUserPresets.json.",
+ "items": {
+ "type": "string",
+ "description": "An optional string representing the name of the preset to inherit from.",
+ "minLength": 1
+ }
+ }
+ ]
+ },
+ "configurePreset": {
+ "type": "string",
+ "description": "An optional string specifying the name of a configure preset to associate with this package preset. If configurePreset is not specified, it must be inherited from the inherits preset (unless this preset is hidden). The build tree directory is inferred from the configure preset.",
+ "minLength": 1
+ },
+ "vendor": {
+ "type": "object",
+ "description": "An optional map containing vendor-specific information. CMake does not interpret the contents of this field except to verify that it is a map if it does exist. However, it should follow the same conventions as the root-level vendor field. If vendors use their own per-preset vendor field, they should implement inheritance in a sensible manner when appropriate.",
+ "properties": {}
+ },
+ "displayName": {
+ "type": "string",
+ "description": "An optional string with a human-friendly name of the preset."
+ },
+ "description": {
+ "type": "string",
+ "description": "An optional string with a human-friendly description of the preset."
+ },
+ "inheritConfigureEnvironment": {
+ "type": "boolean",
+ "description": "An optional boolean that defaults to true. If true, the environment variables from the associated configure preset are inherited after all inherited package preset environments, but before environment variables explicitly specified in this package preset."
+ },
+ "environment": {
+ "type": "object",
+ "description": "An optional map of environment variables. The key is the variable name (which must not be an empty string). Each variable is set regardless of whether or not a value was given to it by the process's environment. This field supports macro expansion, and environment variables in this map may reference each other, and may be listed in any order, as long as such references do not cause a cycle (for example,if ENV_1 is $env{ENV_2}, ENV_2 may not be $env{ENV_1}.) Environment variables are inherited through the inherits field, and the preset's environment will be the union of its own environment and the environment from all its parents. If multiple presets in this union define the same variable, the standard rules of inherits are applied. Setting a variable to null causes it to not be set, even if a value was inherited from another preset.",
+ "properties": {},
+ "additionalProperties": {
+ "anyOf": [
+ {
+ "type": "null",
+ "description": "Setting a variable to null causes it to not be set, even if a value was inherited from another preset."
+ },
+ {
+ "type": "string",
+ "description": "A string representing the value of the variable."
+ }
+ ]
+ },
+ "propertyNames": {
+ "pattern": "^.+$"
+ }
+ },
+ "condition": { "$ref": "#/definitions/topCondition" },
+ "generators": {
+ "type": "array",
+ "description": "An optional list of strings representing generators for CPack to use.",
+ "items": {
+ "type": "string",
+ "description": "An optional string representing the name of the CPack generator to use."
+ }
+ },
+ "configurations": {
+ "type": "array",
+ "description": "An optional list of strings representing build configurations for CPack to package.",
+ "items": {
+ "type": "string",
+ "description": "An optional string representing the name of the configuration to use."
+ }
+ },
+ "variables": {
+ "type": "object",
+ "description": "An optional map of variables to pass to CPack, equivalent to -D arguments. Each key is the name of a variable, and the value is the string to assign to that variable.",
+ "items": {
+ "type": "string",
+ "description": "An optional string representing the value of the variable."
+ }
+ },
+ "configFile": {
+ "type": "string",
+ "description": "An optional string representing the config file for CPack to use."
+ },
+ "output": {
+ "type": "object",
+ "description": "An optional object specifying output options.",
+ "properties": {
+ "debug": {
+ "type": "boolean",
+ "description": "An optional boolean specifying whether or not to print debug information. A value of true is equivalent to passing --debug on the command line."
+ },
+ "verbose": {
+ "type": "boolean",
+ "description": "An optional boolean specifying whether or not to print verbosely. A value of true is equivalent to passing --verbose on the command line."
+ }
+ },
+ "additionalProperties": false
+ },
+ "packageName": {
+ "type": "string",
+ "description": "An optional string representing the package name."
+ },
+ "packageVersion": {
+ "type": "string",
+ "description": "An optional string representing the package version."
+ },
+ "packageDirectory": {
+ "type": "string",
+ "description": "An optional string representing the directory in which to place the package."
+ },
+ "vendorName": {
+ "type": "string",
+ "description": "An optional string representing the vendor name."
+ }
+ },
+ "required": [
+ "name"
+ ]
+ }
+ },
+ "packagePresetsV6": {
+ "type": "array",
+ "description": "An optional array of package preset objects. Used to specify arguments to cpack. Available in version 6 and higher.",
+ "allOf": [
+ { "$ref": "#/definitions/packagePresetsItemsV6" }
+ ],
+ "items": {
+ "type": "object",
+ "properties": {
+ "name": {},
+ "hidden": {},
+ "inherits": {},
+ "configurePreset": {},
+ "vendor": {},
+ "displayName": {},
+ "description": {},
+ "inheritConfigureEnvironment": {},
+ "environment": {},
+ "condition": {},
+ "generators": {},
+ "configurations": {},
+ "variables": {},
+ "configFile": {},
+ "output": {},
+ "packageName": {},
+ "packageVersion": {},
+ "packageDirectory": {},
+ "vendorName": {}
+ },
+ "required": [
+ "name"
+ ],
+ "additionalProperties": false
+ }
+ },
"condition": {
"anyOf": [
{
diff --git a/Help/module/FindOpenSP.rst b/Help/module/FindOpenSP.rst
new file mode 100644
index 0000000..1a3da01
--- /dev/null
+++ b/Help/module/FindOpenSP.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOpenSP.cmake
diff --git a/Help/module/FindSDL_gfx.rst b/Help/module/FindSDL_gfx.rst
new file mode 100644
index 0000000..e05d661
--- /dev/null
+++ b/Help/module/FindSDL_gfx.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindSDL_gfx.cmake
diff --git a/Help/policy/CMP0140.rst b/Help/policy/CMP0140.rst
new file mode 100644
index 0000000..2e2d0c3
--- /dev/null
+++ b/Help/policy/CMP0140.rst
@@ -0,0 +1,17 @@
+CMP0140
+-------
+
+.. versionadded:: 3.25
+
+The :command:`return` command checks its parameters.
+
+The ``OLD`` behavior for this policy is to ignore any parameters given to the
+command.
+The ``NEW`` behavior is to check validity of the parameters.
+
+This policy was introduced in CMake version 3.25.
+CMake version |release| warns when the policy is not set and uses
+``OLD`` behavior. Use the :command:`cmake_policy` command to set
+it to ``OLD`` or ``NEW`` explicitly.
+
+.. include:: DEPRECATED.txt
diff --git a/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
index d93a9c1..a31ee3a 100644
--- a/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_CUDA_KNOWN_FEATURES.rst
@@ -36,4 +36,9 @@ The features known to this version of CMake are:
Compiler mode is at least CUDA/C++ 23.
+``cuda_std_26``
+ .. versionadded:: 3.25
+
+ Compiler mode is at least CUDA/C++ 26.
+
.. include:: CMAKE_LANG_STD_FLAGS.txt
diff --git a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
index 6846850..3832f1a 100644
--- a/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
+++ b/Help/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.rst
@@ -46,6 +46,11 @@ but it does not necessarily imply complete conformance to that standard.
Compiler mode is at least C++ 23.
+``cxx_std_26``
+ .. versionadded:: 3.25
+
+ Compiler mode is at least C++ 26.
+
.. include:: CMAKE_LANG_STD_FLAGS.txt
Low level individual compile features
diff --git a/Help/prop_test/LABELS.rst b/Help/prop_test/LABELS.rst
index a06f152..d827adc 100644
--- a/Help/prop_test/LABELS.rst
+++ b/Help/prop_test/LABELS.rst
@@ -4,7 +4,7 @@ LABELS
Specify a list of text labels associated with a test. The labels are
reported in both the ``ctest`` output summary and in dashboard submissions.
They can also be used to filter the set of tests to be executed (see the
-``ctest -L`` and ``ctest -LE`` :ref:`CTest Options`).
+:option:`ctest -L` and :option:`ctest -LE` options).
See :ref:`Additional Labels` for adding labels to a test dynamically during
test execution.
diff --git a/Help/prop_tgt/COMPILE_WARNING_AS_ERROR.rst b/Help/prop_tgt/COMPILE_WARNING_AS_ERROR.rst
index 19323cb..684b9dd 100644
--- a/Help/prop_tgt/COMPILE_WARNING_AS_ERROR.rst
+++ b/Help/prop_tgt/COMPILE_WARNING_AS_ERROR.rst
@@ -5,8 +5,8 @@ COMPILE_WARNING_AS_ERROR
Specify whether to treat warnings on compile as errors.
If enabled, adds a flag to treat warnings on compile as errors.
-If the ``--compile-no-warning-as-error`` option is given on the
-:manual:`cmake(1)` command line, this property is ignored.
+If the :option:`cmake --compile-no-warning-as-error` option is given
+on the :manual:`cmake(1)` command line, this property is ignored.
This property is not implemented for all compilers. It is silently ignored
if there is no implementation for the compiler being used. The currently
diff --git a/Help/prop_tgt/CUDA_STANDARD.rst b/Help/prop_tgt/CUDA_STANDARD.rst
index 950ba12..ada69b9 100644
--- a/Help/prop_tgt/CUDA_STANDARD.rst
+++ b/Help/prop_tgt/CUDA_STANDARD.rst
@@ -39,6 +39,12 @@ Supported values are:
CUDA C++23
+``26``
+ .. versionadded:: 3.25
+
+ CUDA C++26. CMake 3.25 and later *recognize* ``26`` as a valid value,
+ no version has support for any compiler.
+
If the value requested does not result in a compile flag being added for
the compiler in use, a previous standard flag will be added instead. This
means that using:
diff --git a/Help/prop_tgt/CXX_MODULE_DIRS.rst b/Help/prop_tgt/CXX_MODULE_DIRS.rst
new file mode 100644
index 0000000..fdf3831
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_DIRS.rst
@@ -0,0 +1,17 @@
+CXX_MODULE_DIRS
+---------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Semicolon-separated list of base directories of the target's default
+C++ module set (i.e. the file set with name and type ``CXX_MODULES``). The
+property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+This property is normally only set by :command:`target_sources(FILE_SET)`
+rather than being manipulated directly.
+
+See :prop_tgt:`CXX_MODULE_DIRS_<NAME>` for the list of base directories in
+other C++ module sets.
diff --git a/Help/prop_tgt/CXX_MODULE_DIRS_NAME.rst b/Help/prop_tgt/CXX_MODULE_DIRS_NAME.rst
new file mode 100644
index 0000000..8c27d45
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_DIRS_NAME.rst
@@ -0,0 +1,17 @@
+CXX_MODULE_DIRS_<NAME>
+----------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Semicolon-separated list of base directories of the target's ``<NAME>`` C++
+module set, which has the set type ``CXX_MODULES``. The property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+This property is normally only set by :command:`target_sources(FILE_SET)`
+rather than being manipulated directly.
+
+See :prop_tgt:`CXX_MODULE_DIRS` for the list of base directories in the
+default C++ module set. See :prop_tgt:`CXX_MODULE_SETS` for the file set names
+of all C++ module sets.
diff --git a/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS.rst b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS.rst
new file mode 100644
index 0000000..17e5cf0
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS.rst
@@ -0,0 +1,17 @@
+CXX_MODULE_HEADER_UNIT_DIRS
+---------------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Semicolon-separated list of base directories of the target's default C++
+module header set (i.e. the file set with name and type
+``CXX_MODULE_HEADER_UNITS``). The property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+This property is normally only set by :command:`target_sources(FILE_SET)`
+rather than being manipulated directly.
+
+See :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS_<NAME>` for the list of base directories
+in other C++ module header sets.
diff --git a/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS_NAME.rst b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS_NAME.rst
new file mode 100644
index 0000000..ca30f23
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_DIRS_NAME.rst
@@ -0,0 +1,19 @@
+CXX_MODULE_HEADER_UNIT_DIRS_<NAME>
+----------------------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Semicolon-separated list of base directories of the target's ``<NAME>`` C++
+module header set, which has the set type ``CXX_MODULE_HEADER_UNITS``. The
+property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+This property is normally only set by :command:`target_sources(FILE_SET)`
+rather than being manipulated directly.
+
+See :prop_tgt:`CXX_MODULE_HEADER_UNIT_DIRS` for the list of base directories
+in the default C++ module header set. See
+:prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS` for the file set names of all C++
+module header sets.
diff --git a/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SET.rst b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SET.rst
new file mode 100644
index 0000000..f67a848
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SET.rst
@@ -0,0 +1,18 @@
+CXX_MODULE_HEADER_UNIT_SET
+--------------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Semicolon-separated list of files in the target's default C++ module header
+set, (i.e. the file set with name and type ``CXX_MODULE_HEADER_UNITS``). If
+any of the paths are relative, they are computed relative to the target's
+source directory. The property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+This property is normally only set by :command:`target_sources(FILE_SET)`
+rather than being manipulated directly.
+
+See :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET_<NAME>` for the list of files in
+other C++ module header sets.
diff --git a/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SETS.rst b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SETS.rst
new file mode 100644
index 0000000..7b4bd3f
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SETS.rst
@@ -0,0 +1,18 @@
+CXX_MODULE_HEADER_UNIT_SETS
+---------------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Read-only list of the target's ``PRIVATE`` and ``PUBLIC`` C++ module header
+sets (i.e. all file sets with the type ``CXX_MODULE_HEADER_UNITS``). Files
+listed in these file sets are treated as source files for the purpose of IDE
+integration.
+
+C++ module header sets may be defined using the :command:`target_sources`
+command ``FILE_SET`` option with type ``CXX_MODULE_HEADER_UNITS``.
+
+See also :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET_<NAME>`,
+:prop_tgt:`CXX_MODULE_HEADER_UNIT_SET` and
+:prop_tgt:`INTERFACE_CXX_MODULE_HEADER_UNIT_SETS`.
diff --git a/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SET_NAME.rst b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SET_NAME.rst
new file mode 100644
index 0000000..d328950
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_HEADER_UNIT_SET_NAME.rst
@@ -0,0 +1,19 @@
+CXX_MODULE_HEADER_UNIT_SET_<NAME>
+---------------------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Semicolon-separated list of files in the target's ``<NAME>`` C++ module header
+set, which has the set type ``CXX_MODULE_HEADER_UNITS``. If any of the paths
+are relative, they are computed relative to the target's source directory. The
+property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+This property is normally only set by :command:`target_sources(FILE_SET)`
+rather than being manipulated directly.
+
+See :prop_tgt:`CXX_MODULE_HEADER_UNIT_SET` for the list of files in the
+default C++ module header set. See :prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS` for
+the file set names of all C++ module header sets.
diff --git a/Help/prop_tgt/CXX_MODULE_SET.rst b/Help/prop_tgt/CXX_MODULE_SET.rst
new file mode 100644
index 0000000..ae9000e
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_SET.rst
@@ -0,0 +1,18 @@
+CXX_MODULE_SET
+--------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Semicolon-separated list of files in the target's default C++ module set,
+(i.e. the file set with name and type ``CXX_MODULES``). If any of the paths
+are relative, they are computed relative to the target's source directory. The
+property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+This property is normally only set by :command:`target_sources(FILE_SET)`
+rather than being manipulated directly.
+
+See :prop_tgt:`CXX_MODULE_SET_<NAME>` for the list of files in other C++
+module sets.
diff --git a/Help/prop_tgt/CXX_MODULE_SETS.rst b/Help/prop_tgt/CXX_MODULE_SETS.rst
new file mode 100644
index 0000000..c03df39
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_SETS.rst
@@ -0,0 +1,16 @@
+CXX_MODULE_SETS
+---------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Read-only list of the target's ``PRIVATE`` and ``PUBLIC`` C++ module sets (i.e.
+all file sets with the type ``CXX_MODULES``). Files listed in these file sets are
+treated as source files for the purpose of IDE integration.
+
+C++ module sets may be defined using the :command:`target_sources` command
+``FILE_SET`` option with type ``CXX_MODULES``.
+
+See also :prop_tgt:`CXX_MODULE_SET_<NAME>`, :prop_tgt:`CXX_MODULE_SET` and
+:prop_tgt:`INTERFACE_CXX_MODULE_SETS`.
diff --git a/Help/prop_tgt/CXX_MODULE_SET_NAME.rst b/Help/prop_tgt/CXX_MODULE_SET_NAME.rst
new file mode 100644
index 0000000..27c88f3
--- /dev/null
+++ b/Help/prop_tgt/CXX_MODULE_SET_NAME.rst
@@ -0,0 +1,18 @@
+CXX_MODULE_SET_<NAME>
+---------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Semicolon-separated list of files in the target's ``<NAME>`` C++ module set,
+which has the set type ``CXX_MODULES``. If any of the paths are relative, they
+are computed relative to the target's source directory. The property supports
+:manual:`generator expressions <cmake-generator-expressions(7)>`.
+
+This property is normally only set by :command:`target_sources(FILE_SET)`
+rather than being manipulated directly.
+
+See :prop_tgt:`CXX_MODULE_SET` for the list of files in the default C++ module
+set. See :prop_tgt:`CXX_MODULE_SETS` for the file set names of all C++ module
+sets.
diff --git a/Help/prop_tgt/CXX_STANDARD.rst b/Help/prop_tgt/CXX_STANDARD.rst
index b10d201..9b381e4 100644
--- a/Help/prop_tgt/CXX_STANDARD.rst
+++ b/Help/prop_tgt/CXX_STANDARD.rst
@@ -37,6 +37,12 @@ Supported values are:
C++23
+``26``
+ .. versionadded:: 3.25
+
+ C++26. CMake 3.25 and later *recognize* ``26`` as a valid value,
+ no version has support for any compiler.
+
If the value requested does not result in a compile flag being added for
the compiler in use, a previous standard flag will be added instead. This
means that using:
diff --git a/Help/prop_tgt/EXPORT_NO_SYSTEM.rst b/Help/prop_tgt/EXPORT_NO_SYSTEM.rst
new file mode 100644
index 0000000..c93d1a5
--- /dev/null
+++ b/Help/prop_tgt/EXPORT_NO_SYSTEM.rst
@@ -0,0 +1,11 @@
+EXPORT_NO_SYSTEM
+----------------
+
+.. versionadded:: 3.25
+
+Specifies that :command:`install(EXPORT)` and :command:`export` commands will
+generate a imported target with :prop_tgt:`SYSTEM` property `OFF`.
+
+See the :prop_tgt:`NO_SYSTEM_FROM_IMPORTED` target property to set this
+behavior on the target consuming the include directories rather than
+providing them.
diff --git a/Help/prop_tgt/HIP_STANDARD.rst b/Help/prop_tgt/HIP_STANDARD.rst
index 0c767c6..9de8730 100644
--- a/Help/prop_tgt/HIP_STANDARD.rst
+++ b/Help/prop_tgt/HIP_STANDARD.rst
@@ -25,6 +25,12 @@ Supported values are:
``23``
HIP C++23
+``26``
+ .. versionadded:: 3.25
+
+ HIP C++26. CMake 3.25 and later *recognize* ``26`` as a valid value,
+ no version has support for any compiler.
+
If the value requested does not result in a compile flag being added for
the compiler in use, a previous standard flag will be added instead. This
means that using:
diff --git a/Help/prop_tgt/IMPORTED_NO_SYSTEM.rst b/Help/prop_tgt/IMPORTED_NO_SYSTEM.rst
index ee22d6f..913d9f2 100644
--- a/Help/prop_tgt/IMPORTED_NO_SYSTEM.rst
+++ b/Help/prop_tgt/IMPORTED_NO_SYSTEM.rst
@@ -3,11 +3,21 @@ IMPORTED_NO_SYSTEM
.. versionadded:: 3.23
+.. deprecated:: 3.25
+
+ ``IMPORTED_NO_SYSTEM`` is deprecated. Set :prop_tgt:`SYSTEM` to `OFF`
+ instead if you don't want target's include directories to be ``SYSTEM``
+ when compiling consumers. Set :prop_tgt:`EXPORT_NO_SYSTEM` to `ON` instead
+ if you don't want the include directories of the imported target generated
+ by :command:`install(EXPORT)` and :command:`export` commands to be
+ ``SYSTEM`` when compiling consumers.
+
Specifies that an :ref:`Imported Target <Imported Targets>` is not
a ``SYSTEM`` library. This has the following effects:
* Entries of :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` are not treated
- as ``SYSTEM`` include directories when compiling consumers, as they
+ as ``SYSTEM`` include directories when compiling consumers (regardless of
+ the value of the consumed target's :prop_tgt:`SYSTEM` property), as they
would be by default. Entries of
:prop_tgt:`INTERFACE_SYSTEM_INCLUDE_DIRECTORIES` are not affected,
and will always be treated as ``SYSTEM`` include directories.
diff --git a/Help/prop_tgt/INTERFACE_CXX_MODULE_HEADER_UNIT_SETS.rst b/Help/prop_tgt/INTERFACE_CXX_MODULE_HEADER_UNIT_SETS.rst
new file mode 100644
index 0000000..eb3a9ff
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_CXX_MODULE_HEADER_UNIT_SETS.rst
@@ -0,0 +1,16 @@
+INTERFACE_CXX_MODULE_HEADER_UNIT_SETS
+-------------------------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Read-only list of the target's ``PUBLIC`` C++ module header sets (i.e. all
+file sets with the type ``CXX_MODULE_HEADER_UNITS``). Files listed in these
+C++ module header sets can be installed with :command:`install(TARGETS)` and
+exported with :command:`install(EXPORT)` and :command:`export`.
+
+C++ module header sets may be defined using the :command:`target_sources`
+command ``FILE_SET`` option with type ``CXX_MODULE_HEADER_UNITS``.
+
+See also :prop_tgt:`CXX_MODULE_HEADER_UNIT_SETS`.
diff --git a/Help/prop_tgt/INTERFACE_CXX_MODULE_SETS.rst b/Help/prop_tgt/INTERFACE_CXX_MODULE_SETS.rst
new file mode 100644
index 0000000..cc30386
--- /dev/null
+++ b/Help/prop_tgt/INTERFACE_CXX_MODULE_SETS.rst
@@ -0,0 +1,16 @@
+INTERFACE_CXX_MODULE_SETS
+-------------------------
+
+.. note ::
+
+ Experimental. Gated by ``CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API``
+
+Read-only list of the target's ``PUBLIC`` C++ module sets (i.e. all file sets
+with the type ``CXX_MODULES``). Files listed in these C++ module sets can be
+installed with :command:`install(TARGETS)` and exported with
+:command:`install(EXPORT)` and :command:`export`.
+
+C++ module sets may be defined using the :command:`target_sources` command
+``FILE_SET`` option with type ``CXX_MODULES``.
+
+See also :prop_tgt:`CXX_MODULE_SETS`.
diff --git a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
index cba8ac9..2e039bd 100644
--- a/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
+++ b/Help/prop_tgt/LANG_COMPILER_LAUNCHER.rst
@@ -14,3 +14,8 @@ its arguments to the tool. Some example tools are distcc and ccache.
This property is initialized by the value of
the :variable:`CMAKE_<LANG>_COMPILER_LAUNCHER` variable if it is set
when a target is created.
+
+.. versionadded:: 3.25
+
+ The property value may use
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
index 9b978b2..9f13d38 100644
--- a/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
+++ b/Help/prop_tgt/MSVC_RUNTIME_LIBRARY.rst
@@ -21,7 +21,9 @@ support per-configuration specification. For example, the code:
selects for the target ``foo`` a multi-threaded statically-linked runtime
library with or without debug information depending on the configuration.
-If this property is not set then CMake uses the default value
+The property is initialized from the value of the
+:variable:`CMAKE_MSVC_RUNTIME_LIBRARY` variable, if it is set.
+If the property is not set, then CMake uses the default value
``MultiThreaded$<$<CONFIG:Debug>:Debug>DLL`` to select a MSVC runtime library.
.. note::
diff --git a/Help/prop_tgt/OBJCXX_STANDARD.rst b/Help/prop_tgt/OBJCXX_STANDARD.rst
index 654e687..6ac8216 100644
--- a/Help/prop_tgt/OBJCXX_STANDARD.rst
+++ b/Help/prop_tgt/OBJCXX_STANDARD.rst
@@ -31,6 +31,12 @@ Supported values are:
Objective C++23
+``26``
+ .. versionadded:: 3.25
+
+ Objective C++26. CMake 3.25 and later *recognize* ``26`` as a valid value,
+ no version has support for any compiler.
+
If the value requested does not result in a compile flag being added for
the compiler in use, a previous standard flag will be added instead. This
means that using:
diff --git a/Help/prop_tgt/SYSTEM.rst b/Help/prop_tgt/SYSTEM.rst
new file mode 100644
index 0000000..2db6aed
--- /dev/null
+++ b/Help/prop_tgt/SYSTEM.rst
@@ -0,0 +1,16 @@
+SYSTEM
+------
+
+.. versionadded:: 3.25
+
+Specifies that a target is a ``SYSTEM`` library. This has the following effects:
+
+* Entries of :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` are treated as ``SYSTEM``
+ include directories when compiling consumers.
+ Entries of :prop_tgt:`INTERFACE_SYSTEM_INCLUDE_DIRECTORIES` are not affected,
+ and will always be treated as ``SYSTEM`` include directories.
+
+For imported targets, this property has a default value `ON`, which means that their
+`INTERFACE_INCLUDE_DIRECTORIES` are treated as ``SYSTEM`` by default. If their
+`SYSTEM` property is `OFF`, then their `INTERFACE_INCLUDE_DIRECTORIES` will not be
+treated as ``SYSTEM``, regardless of the value of `IMPORTED_NO_SYSTEM` property.
diff --git a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
index 8f46d2f..fa3c5bc 100644
--- a/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
+++ b/Help/prop_tgt/XCODE_GENERATE_SCHEME.rst
@@ -30,6 +30,9 @@ at target creation time.
- :prop_tgt:`XCODE_SCHEME_THREAD_SANITIZER_STOP`
- :prop_tgt:`XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER`
- :prop_tgt:`XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP`
+- :prop_tgt:`XCODE_SCHEME_LAUNCH_CONFIGURATION`
+- :prop_tgt:`XCODE_SCHEME_ENABLE_GPU_API_VALIDATION`
+- :prop_tgt:`XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION`
- :prop_tgt:`XCODE_SCHEME_ZOMBIE_OBJECTS`
The following target properties will be applied on the
@@ -41,4 +44,5 @@ The following target properties will be applied on the
- :prop_tgt:`XCODE_SCHEME_ENABLE_GPU_FRAME_CAPTURE_MODE`
- :prop_tgt:`XCODE_SCHEME_ENVIRONMENT`
- :prop_tgt:`XCODE_SCHEME_EXECUTABLE`
+- :prop_tgt:`XCODE_SCHEME_LAUNCH_MODE`
- :prop_tgt:`XCODE_SCHEME_WORKING_DIRECTORY`
diff --git a/Help/prop_tgt/XCODE_SCHEME_ENABLE_GPU_API_VALIDATION.rst b/Help/prop_tgt/XCODE_SCHEME_ENABLE_GPU_API_VALIDATION.rst
new file mode 100644
index 0000000..3b801c5
--- /dev/null
+++ b/Help/prop_tgt/XCODE_SCHEME_ENABLE_GPU_API_VALIDATION.rst
@@ -0,0 +1,14 @@
+XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+--------------------------------------
+
+.. versionadded:: 3.25
+
+Property value for ``Metal: API Validation`` in the Options section of
+the generated Xcode scheme.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION`
+if it is set when a target is created.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION.rst b/Help/prop_tgt/XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION.rst
new file mode 100644
index 0000000..5358087
--- /dev/null
+++ b/Help/prop_tgt/XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION.rst
@@ -0,0 +1,14 @@
+XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
+-----------------------------------------
+
+.. versionadded:: 3.25
+
+Property value for ``Metal: Shader Validation`` in the Options section of
+the generated Xcode scheme.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION`
+if it is set when a target is created.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_LAUNCH_CONFIGURATION.rst b/Help/prop_tgt/XCODE_SCHEME_LAUNCH_CONFIGURATION.rst
new file mode 100644
index 0000000..9643322
--- /dev/null
+++ b/Help/prop_tgt/XCODE_SCHEME_LAUNCH_CONFIGURATION.rst
@@ -0,0 +1,13 @@
+XCODE_SCHEME_LAUNCH_CONFIGURATION
+---------------------------------
+
+.. versionadded:: 3.25
+
+Set the build configuration to run the target.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION`
+if it is set when a target is created.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Help/prop_tgt/XCODE_SCHEME_LAUNCH_MODE.rst b/Help/prop_tgt/XCODE_SCHEME_LAUNCH_MODE.rst
new file mode 100644
index 0000000..df5ae07
--- /dev/null
+++ b/Help/prop_tgt/XCODE_SCHEME_LAUNCH_MODE.rst
@@ -0,0 +1,22 @@
+XCODE_SCHEME_LAUNCH_MODE
+------------------------
+
+.. versionadded:: 3.25
+
+Property value for ``Launch`` in the Info section of the generated Xcode
+scheme.
+
+Possible values are:
+
+``AUTO``
+ Launch automatically. This is the default.
+
+``WAIT``
+ Wait for the executable to be launched.
+
+This property is initialized by the value of the variable
+:variable:`CMAKE_XCODE_SCHEME_LAUNCH_MODE` if it is set when a target is
+created.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Help/release/dev/0-sample-topic.rst b/Help/release/dev/0-sample-topic.rst
new file mode 100644
index 0000000..e4cc01e
--- /dev/null
+++ b/Help/release/dev/0-sample-topic.rst
@@ -0,0 +1,7 @@
+0-sample-topic
+--------------
+
+* This is a sample release note for the change in a topic.
+ Developers should add similar notes for each topic branch
+ making a noteworthy change. Each document should be named
+ and titled to match the topic name to avoid merge conflicts.
diff --git a/Help/release/dev/E-capabilities-tls.rst b/Help/release/dev/E-capabilities-tls.rst
new file mode 100644
index 0000000..e2324d2
--- /dev/null
+++ b/Help/release/dev/E-capabilities-tls.rst
@@ -0,0 +1,5 @@
+E-capabilities-tls
+------------------
+
+* The :manual:`cmake -E capabilities <cmake(1)>` command gained a new ``tls``
+ field that tells whether or not TLS is enabled.
diff --git a/Help/release/dev/FindOpenSP-module.rst b/Help/release/dev/FindOpenSP-module.rst
new file mode 100644
index 0000000..9df6815
--- /dev/null
+++ b/Help/release/dev/FindOpenSP-module.rst
@@ -0,0 +1,4 @@
+FindOpenSP-module
+-----------------
+
+* The :module:`FindOpenSP` module was added to find the OpenSP library.
diff --git a/Help/release/dev/FindVulkan-dxc.rst b/Help/release/dev/FindVulkan-dxc.rst
new file mode 100644
index 0000000..e22f016
--- /dev/null
+++ b/Help/release/dev/FindVulkan-dxc.rst
@@ -0,0 +1,5 @@
+FindVulkan-dxc
+--------------
+
+* The :module:`FindVulkan` module gained support for a DirectX Shader Compiler
+ component, ``dxc``.
diff --git a/Help/release/dev/LINUX.rst b/Help/release/dev/LINUX.rst
new file mode 100644
index 0000000..45b7029
--- /dev/null
+++ b/Help/release/dev/LINUX.rst
@@ -0,0 +1,4 @@
+Variables
+---------
+
+* The :variable:`LINUX` variable is set to true when the target system is Linux.
diff --git a/Help/release/dev/block-command.rst b/Help/release/dev/block-command.rst
new file mode 100644
index 0000000..a740c0b
--- /dev/null
+++ b/Help/release/dev/block-command.rst
@@ -0,0 +1,5 @@
+block-command
+-------------
+
+* CMake language gains the commands :command:`block` and :command:`endblock` to
+ manage specific scopes (policy or variable) for group of commands.
diff --git a/Help/release/dev/bsd-variables.rst b/Help/release/dev/bsd-variables.rst
new file mode 100644
index 0000000..9d59edc
--- /dev/null
+++ b/Help/release/dev/bsd-variables.rst
@@ -0,0 +1,9 @@
+bsd-variables
+-------------
+
+* The :variable:`BSD` variable is set to true when the target system
+ is BSD (DragonFlyBSD, FreeBSD, OpenBSD, or NetBSD)
+* The :variable:`DRAGONFLYBSD` variable is set to true when the target system is DragonFlyBSD.
+* The :variable:`FREEBSD` variable is set to true when the target system is FreeBSD.
+* The :variable:`NETBSD` variable is set to true when the target system is NetBSD.
+* The :variable:`OPENBSD` variable is set to true when the target system is OpenBSD.
diff --git a/Help/release/dev/cmake-E-env-modify.rst b/Help/release/dev/cmake-E-env-modify.rst
new file mode 100644
index 0000000..ea4a622
--- /dev/null
+++ b/Help/release/dev/cmake-E-env-modify.rst
@@ -0,0 +1,5 @@
+cmake-E-env-modify
+------------------
+
+* A new ``--modify`` flag was added to :option:`cmake -E env <cmake_E env>` to support :prop_test:`ENVIRONMENT_MODIFICATION`
+ operations.
diff --git a/Help/release/dev/cmake-presets-package.rst b/Help/release/dev/cmake-presets-package.rst
new file mode 100644
index 0000000..8f7ea6b
--- /dev/null
+++ b/Help/release/dev/cmake-presets-package.rst
@@ -0,0 +1,5 @@
+cmake-presets-package
+---------------------
+
+* The :manual:`cmake-presets(7)` schema version has been bumped to ``6``.
+* The :manual:`cmake-presets(7)` format now supports a ``packagePresets`` field.
diff --git a/Help/release/dev/cmake_language_GET_MESSAGE_LOG_LEVEL.rst b/Help/release/dev/cmake_language_GET_MESSAGE_LOG_LEVEL.rst
new file mode 100644
index 0000000..6e99a05
--- /dev/null
+++ b/Help/release/dev/cmake_language_GET_MESSAGE_LOG_LEVEL.rst
@@ -0,0 +1,6 @@
+cmake-language_GET_MESSAGE_LOG_LEVEL
+------------------------------------
+
+* The :command:`cmake_language` command gained a new
+ ``GET_MESSAGE_LOG_LEVEL`` sub-command. It can be used to
+ query the current message logging level.
diff --git a/Help/release/dev/compiler-launcher-genexp.rst b/Help/release/dev/compiler-launcher-genexp.rst
new file mode 100644
index 0000000..0e79992
--- /dev/null
+++ b/Help/release/dev/compiler-launcher-genexp.rst
@@ -0,0 +1,5 @@
+compiler-launcher-genexp
+------------------------
+
+* The :prop_tgt:`<LANG>_COMPILER_LAUNCHER` target property now supports
+ :manual:`generator expressions <cmake-generator-expressions(7)>`.
diff --git a/Help/release/dev/cpack-archive-custom-extension.rst b/Help/release/dev/cpack-archive-custom-extension.rst
new file mode 100644
index 0000000..38ad36f
--- /dev/null
+++ b/Help/release/dev/cpack-archive-custom-extension.rst
@@ -0,0 +1,6 @@
+cpack-archive-custom-extension
+------------------------------
+
+* The :cpack_gen:`CPack Archive Generator` gained a new
+ :variable:`CPACK_ARCHIVE_FILE_EXTENSION` variable to control
+ the package file name extension.
diff --git a/Help/release/dev/cpack-reuse-cmake-tools.rst b/Help/release/dev/cpack-reuse-cmake-tools.rst
new file mode 100644
index 0000000..144a6b3
--- /dev/null
+++ b/Help/release/dev/cpack-reuse-cmake-tools.rst
@@ -0,0 +1,7 @@
+cpack-reuse-cmake-tools
+-----------------------
+
+* The :module:`CPack` module gained the :variable:`CPACK_READELF_EXECUTABLE`,
+ :variable:`CPACK_OBJCOPY_EXECUTABLE`, and
+ :variable:`CPACK_OBJDUMP_EXECUTABLE` variables to control the locations
+ of binutils used by :manual:`cpack(1)`.
diff --git a/Help/release/dev/cuda-device-lto.rst b/Help/release/dev/cuda-device-lto.rst
new file mode 100644
index 0000000..113062b
--- /dev/null
+++ b/Help/release/dev/cuda-device-lto.rst
@@ -0,0 +1,7 @@
+cuda-device-lto
+---------------
+
+* ``CUDA`` language now supports device link time optimization when using
+ ``nvcc``. The :variable:`CMAKE_INTERPROCEDURAL_OPTIMIZATION` variable and
+ the associated :prop_tgt:`INTERPROCEDURAL_OPTIMIZATION` target property will
+ activate device LTO.
diff --git a/Help/release/dev/cxx_std_26.rst b/Help/release/dev/cxx_std_26.rst
new file mode 100644
index 0000000..831f567
--- /dev/null
+++ b/Help/release/dev/cxx_std_26.rst
@@ -0,0 +1,8 @@
+cxx_std_26
+----------
+
+* C++26 compiler modes may now be specified via the :prop_tgt:`CXX_STANDARD`,
+ :prop_tgt:`CUDA_STANDARD`, :prop_tgt:`HIP_STANDARD`, or
+ :prop_tgt:`OBJCXX_STANDARD` target properties,
+ or via the :manual:`Compile Features <cmake-compile-features(7)>`
+ functionality's ``cxx_std_26`` meta-feature.
diff --git a/Help/release/dev/find-cuda-toolkit-nvtx3.rst b/Help/release/dev/find-cuda-toolkit-nvtx3.rst
new file mode 100644
index 0000000..b16ed9f
--- /dev/null
+++ b/Help/release/dev/find-cuda-toolkit-nvtx3.rst
@@ -0,0 +1,8 @@
+find-cuda-toolkit-nvtx3
+-----------------------
+
+* The :module:`FindCUDAToolkit` module now provides a target for
+ :ref:`nvtx3 <cuda_toolkit_nvtx3>` for CUDA 10.0+, which supersedes
+ :ref:`nvToolsExt <cuda_toolkit_nvToolsExt>`. A deprecation warning is emitted
+ when using ``nvToolsExt`` if the project requires CMake 3.25 and CUDA 10.0+
+ is used.
diff --git a/Help/release/dev/find_item-VALIDATOR.rst b/Help/release/dev/find_item-VALIDATOR.rst
new file mode 100644
index 0000000..2cda421
--- /dev/null
+++ b/Help/release/dev/find_item-VALIDATOR.rst
@@ -0,0 +1,6 @@
+find_item-VALIDATOR
+-------------------
+
+* :command:`find_file`, :command:`find_path`, :command:`find_library`, and
+ :command:`find_program` commands gain the capability to specify a function
+ which will be called for each found item to validate it.
diff --git a/Help/release/dev/find_package-one-more-path.rst b/Help/release/dev/find_package-one-more-path.rst
new file mode 100644
index 0000000..554b67d
--- /dev/null
+++ b/Help/release/dev/find_package-one-more-path.rst
@@ -0,0 +1,6 @@
+find_package-one-more-path
+--------------------------
+
+* The :command:`find_package` command now considers paths of
+ the form ``<prefix>/<name>*/(cmake|CMake)/<name>*/`` when
+ searching for package configuration files.
diff --git a/Help/release/dev/finddoxygen-better-version-checking.rst b/Help/release/dev/finddoxygen-better-version-checking.rst
new file mode 100644
index 0000000..3c2215d
--- /dev/null
+++ b/Help/release/dev/finddoxygen-better-version-checking.rst
@@ -0,0 +1,11 @@
+finddoxygen-better-version-checking
+-----------------------------------
+
+* The :module:`FindDoxygen` module now evaluates as many candidate
+ Doxygen installs as are necessary to satisfy version constraints,
+ with the package considered to be not found if none are available.
+
+* The :module:`FindDoxygen` module now handles version ranges.
+
+* The :module:`FindDoxygen` module now ignores non-semantic portions
+ of the output from Doxygen's `--version` option.
diff --git a/Help/release/dev/findopenal-add-import-library.rst b/Help/release/dev/findopenal-add-import-library.rst
new file mode 100644
index 0000000..6c9c93f
--- /dev/null
+++ b/Help/release/dev/findopenal-add-import-library.rst
@@ -0,0 +1,4 @@
+findopenal-add-import-library
+-----------------------------
+
+* The :module:`FindOpenAL` module now provides an imported target.
diff --git a/Help/release/dev/findvulkan-volk.rst b/Help/release/dev/findvulkan-volk.rst
new file mode 100644
index 0000000..cb77078
--- /dev/null
+++ b/Help/release/dev/findvulkan-volk.rst
@@ -0,0 +1,5 @@
+findvulkan-volk
+---------------
+
+* The :module:`FindVulkan` module now includes a ``volk`` component
+ for the Volk open source vulkan meta-loader.
diff --git a/Help/release/dev/p1689r5.rst b/Help/release/dev/p1689r5.rst
new file mode 100644
index 0000000..a630dc4
--- /dev/null
+++ b/Help/release/dev/p1689r5.rst
@@ -0,0 +1,6 @@
+p1689r5
+-------
+
+* C++ module scanning now supports the latest revision, `P1689R5`_.
+
+.. _`P1689r5`: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1689r5.html
diff --git a/Help/release/dev/return-PROPAGATE.rst b/Help/release/dev/return-PROPAGATE.rst
new file mode 100644
index 0000000..7308d20
--- /dev/null
+++ b/Help/release/dev/return-PROPAGATE.rst
@@ -0,0 +1,5 @@
+return-PROPAGATE
+----------------
+
+* The :command:`return` command gains the capability to propagate variables to
+ the include directory of function caller scope. See policy :policy:`CMP0140`.
diff --git a/Help/release/dev/system.rst b/Help/release/dev/system.rst
new file mode 100644
index 0000000..7cc841e
--- /dev/null
+++ b/Help/release/dev/system.rst
@@ -0,0 +1,15 @@
+system
+------
+
+* The :prop_tgt:`SYSTEM` target property was added to specify
+ that a target should be treated as a system library (i.e.
+ its include directories are automatically ``SYSTEM`` when
+ compiling consumers).
+
+* The :prop_tgt:`EXPORT_NO_SYSTEM` target property was added to
+ specify that :command:`install(EXPORT)` and :command:`export`
+ commands will generate a imported target with
+ :prop_tgt:`SYSTEM` property `OFF`.
+
+* The :prop_tgt:`IMPORTED_NO_SYSTEM` target property was deprecated
+ in favor of :prop_tgt:`SYSTEM` and :prop_tgt:`EXPORT_NO_SYSTEM`.
diff --git a/Help/release/dev/try_compile-signatures.rst b/Help/release/dev/try_compile-signatures.rst
new file mode 100644
index 0000000..d477d989
--- /dev/null
+++ b/Help/release/dev/try_compile-signatures.rst
@@ -0,0 +1,8 @@
+try_compile-signatures
+----------------------
+
+* The :command:`try_compile` and :command:`try_run` commands gained new
+ signatures that more consistently use keyword dispatch and do not require a
+ binary directory to be specified. Additionally, these signatures use a
+ unique directory for each invocation, which allows multiple outputs to be
+ preserved when using ``--debug-trycompile``.
diff --git a/Help/release/dev/try_run_split_output.rst b/Help/release/dev/try_run_split_output.rst
new file mode 100644
index 0000000..98aedd6
--- /dev/null
+++ b/Help/release/dev/try_run_split_output.rst
@@ -0,0 +1,6 @@
+try_run_split_output
+--------------------
+
+* The :command:`try_run` command gained ``RUN_OUTPUT_STDOUT_VARIABLE``
+ and ``RUN_OUTPUT_STDERR_VARIABLE`` options to capture stdout and stderr
+ separately from the output of the compiled program.
diff --git a/Help/release/dev/xcode-gpu-validation.rst b/Help/release/dev/xcode-gpu-validation.rst
new file mode 100644
index 0000000..86f7e96
--- /dev/null
+++ b/Help/release/dev/xcode-gpu-validation.rst
@@ -0,0 +1,12 @@
+xcode-gpu-validation
+--------------------
+
+* The :variable:`CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION` variable and
+ corresponding :prop_tgt:`XCODE_SCHEME_ENABLE_GPU_API_VALIDATION` target
+ property were added to tell the :generator:`Xcode` generator what to put
+ in the scheme's ``Metal: API Validation`` setting.
+
+* The :variable:`CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION` variable and
+ corresponding :prop_tgt:`XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION` target
+ property were added to tell the :generator:`Xcode` generator what to put
+ in the scheme's ``Metal: Shader Validation`` setting.
diff --git a/Help/release/dev/xcode-launch-mode.rst b/Help/release/dev/xcode-launch-mode.rst
new file mode 100644
index 0000000..701b502
--- /dev/null
+++ b/Help/release/dev/xcode-launch-mode.rst
@@ -0,0 +1,12 @@
+xcode-launch-mode
+-----------------
+
+* The :variable:`CMAKE_XCODE_SCHEME_LAUNCH_MODE` variable and corresponding
+ :prop_tgt:`XCODE_SCHEME_LAUNCH_MODE` target property were added to tell
+ the :generator:`Xcode` generator what to put in the scheme's "Launch"
+ mode setting.
+
+* The :variable:`CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION` variable and
+ corresponding :prop_tgt:`XCODE_SCHEME_LAUNCH_CONFIGURATION` target
+ property were added to tell the :generator:`Xcode` generator what
+ configuration to put in the scheme's Launch action.
diff --git a/Help/release/index.rst b/Help/release/index.rst
index 4dfac8a..11d5a11 100644
--- a/Help/release/index.rst
+++ b/Help/release/index.rst
@@ -7,6 +7,8 @@ CMake Release Notes
This file should include the adjacent "dev.txt" file
in development versions but not in release versions.
+.. include:: dev.txt
+
Releases
========
diff --git a/Help/variable/BSD.rst b/Help/variable/BSD.rst
new file mode 100644
index 0000000..0b3e5dc
--- /dev/null
+++ b/Help/variable/BSD.rst
@@ -0,0 +1,6 @@
+BSD
+---
+
+.. versionadded:: 3.25
+
+Set to true when the target system is BSD (DragonFlyBSD, FreeBSD, OpenBSD, or NetBSD)
diff --git a/Help/variable/CMAKE_BINARY_DIR.rst b/Help/variable/CMAKE_BINARY_DIR.rst
index 3b323b7..f9c7689 100644
--- a/Help/variable/CMAKE_BINARY_DIR.rst
+++ b/Help/variable/CMAKE_BINARY_DIR.rst
@@ -7,7 +7,7 @@ This is the full path to the top level of the current CMake build
tree. For an in-source build, this would be the same as
:variable:`CMAKE_SOURCE_DIR`.
-When run in -P script mode, CMake sets the variables
+When run in :option:`-P <cmake_P -P>` script mode, CMake sets the variables
:variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
:variable:`CMAKE_CURRENT_BINARY_DIR` and
:variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
diff --git a/Help/variable/CMAKE_CPACK_COMMAND.rst b/Help/variable/CMAKE_CPACK_COMMAND.rst
index 3a81d68..f851a18 100644
--- a/Help/variable/CMAKE_CPACK_COMMAND.rst
+++ b/Help/variable/CMAKE_CPACK_COMMAND.rst
@@ -5,6 +5,6 @@ CMAKE_CPACK_COMMAND
Full path to :manual:`cpack(1)` command installed with CMake.
-This is the full path to the CPack executable :manual:`cpack(1)` which is
-useful from custom commands that want to use the :manual:`cmake(1)` ``-E``
-option for portable system commands.
+This is the full path to the CPack executable :manual:`cpack(1)`
+that can be used for custom commands or tests to invoke
+CPack commands.
diff --git a/Help/variable/CMAKE_CTEST_COMMAND.rst b/Help/variable/CMAKE_CTEST_COMMAND.rst
index b2942e2..a3b751f 100644
--- a/Help/variable/CMAKE_CTEST_COMMAND.rst
+++ b/Help/variable/CMAKE_CTEST_COMMAND.rst
@@ -3,6 +3,6 @@ CMAKE_CTEST_COMMAND
Full path to :manual:`ctest(1)` command installed with CMake.
-This is the full path to the CTest executable :manual:`ctest(1)` which is
-useful from custom commands that want to use the :manual:`cmake(1)` ``-E``
-option for portable system commands.
+This is the full path to the CTest executable :manual:`ctest(1)`
+that can be used for custom commands or tests to invoke
+CTest commands.
diff --git a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
index 8fc85ee..6f82dcc 100644
--- a/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_BINARY_DIR.rst
@@ -9,7 +9,7 @@ create a binary directory in the build tree, and as it is being
processed this variable will be set. For in-source builds this is the
current source directory being processed.
-When run in -P script mode, CMake sets the variables
+When run in :option:`-P <cmake_P -P>` script mode, CMake sets the variables
:variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
:variable:`CMAKE_CURRENT_BINARY_DIR` and
:variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
diff --git a/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst b/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst
index 1a25efc..0678f99 100644
--- a/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst
+++ b/Help/variable/CMAKE_CURRENT_SOURCE_DIR.rst
@@ -6,7 +6,7 @@ The path to the source directory currently being processed.
This is the full path to the source directory that is currently being
processed by cmake.
-When run in -P script mode, CMake sets the variables
+When run in :option:`-P <cmake_P -P>` script mode, CMake sets the variables
:variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
:variable:`CMAKE_CURRENT_BINARY_DIR` and
:variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
diff --git a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
index 53a19dc..a7e9029 100644
--- a/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
+++ b/Help/variable/CMAKE_EXPORT_COMPILE_COMMANDS.rst
@@ -33,7 +33,7 @@ property for all targets.
.. note::
This option is implemented only by :ref:`Makefile Generators`
- and the :generator:`Ninja`. It is ignored on other generators.
+ and :ref:`Ninja Generators`. It is ignored on other generators.
This option currently does not work well in combination with
the :prop_tgt:`UNITY_BUILD` target property or the
diff --git a/Help/variable/CMAKE_FIND_DEBUG_MODE.rst b/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
index 8f2a82f..48b0dce 100644
--- a/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
+++ b/Help/variable/CMAKE_FIND_DEBUG_MODE.rst
@@ -13,7 +13,7 @@ error:
* :command:`find_package`
Output is designed for human consumption and not for parsing.
-Enabling this variable is equivalent to using :manual:`cmake <cmake(1)>` ``--debug-find``
+Enabling this variable is equivalent to using :option:`cmake --debug-find`
with the added ability to enable debugging for a subset of find calls.
.. code-block:: cmake
diff --git a/Help/variable/CMAKE_GENERATOR.rst b/Help/variable/CMAKE_GENERATOR.rst
index ec52cd4..0e249eb 100644
--- a/Help/variable/CMAKE_GENERATOR.rst
+++ b/Help/variable/CMAKE_GENERATOR.rst
@@ -7,6 +7,6 @@ The name of the generator that is being used to generate the build
files. (e.g. ``Unix Makefiles``, ``Ninja``, etc.)
The value of this variable should never be modified by project code.
-A generator may be selected via the :manual:`cmake(1)` ``-G`` option,
+A generator may be selected via the :option:`cmake -G` option,
interactively in :manual:`cmake-gui(1)`, or via the :envvar:`CMAKE_GENERATOR`
environment variable.
diff --git a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
index b17d83a..acb7b2e 100644
--- a/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
+++ b/Help/variable/CMAKE_GENERATOR_PLATFORM.rst
@@ -7,7 +7,7 @@ Generator-specific target platform specification provided by user.
Some CMake generators support a target platform name to be given
to the native build system to choose a compiler toolchain.
-If the user specifies a platform name (e.g. via the :manual:`cmake(1)` ``-A``
+If the user specifies a platform name (e.g. via the :option:`cmake -A`
option or via the :envvar:`CMAKE_GENERATOR_PLATFORM` environment variable)
the value will be available in this variable.
diff --git a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
index 45f2d32..4855477 100644
--- a/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
+++ b/Help/variable/CMAKE_GENERATOR_TOOLSET.rst
@@ -5,7 +5,7 @@ Native build system toolset specification provided by user.
Some CMake generators support a toolset specification to tell the
native build system how to choose a compiler. If the user specifies
-a toolset (e.g. via the :manual:`cmake(1)` ``-T`` option or via
+a toolset (e.g. via the :option:`cmake -T` option or via
the :envvar:`CMAKE_GENERATOR_TOOLSET` environment variable) the value
will be available in this variable.
diff --git a/Help/variable/CMAKE_INSTALL_PREFIX.rst b/Help/variable/CMAKE_INSTALL_PREFIX.rst
index 6d42ea8..1636739 100644
--- a/Help/variable/CMAKE_INSTALL_PREFIX.rst
+++ b/Help/variable/CMAKE_INSTALL_PREFIX.rst
@@ -27,8 +27,9 @@ first :command:`project` invocation.
The ``CMAKE_INSTALL_PREFIX`` may be defined when configuring a build tree
to set its installation prefix. Or, when using the :manual:`cmake(1)`
-command-line tool's ``--install`` mode, one may specify a different prefix
-using the ``--prefix`` option:
+command-line tool's :option:`--install <cmake --install>` mode, one may
+specify a different prefix using the :option:`--prefix <cmake --prefix>`
+option:
.. code-block:: shell
diff --git a/Help/variable/CMAKE_LANG_COMPILER.rst b/Help/variable/CMAKE_LANG_COMPILER.rst
index e694b33..db8f4e1 100644
--- a/Help/variable/CMAKE_LANG_COMPILER.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER.rst
@@ -14,7 +14,8 @@ This variable can be set by the user during the first time a build tree is confi
If a non-full path value is supplied then CMake will resolve the full path of
the compiler.
-The variable could be set in a user supplied toolchain file or via `-D` on the command line.
+The variable could be set in a user supplied toolchain file or via
+:option:`-D <cmake -D>` on the command line.
.. note::
Options that are required to make the compiler work correctly can be included
diff --git a/Help/variable/CMAKE_LANG_COMPILER_ID.rst b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
index 6a0a1d9..f0534ba 100644
--- a/Help/variable/CMAKE_LANG_COMPILER_ID.rst
+++ b/Help/variable/CMAKE_LANG_COMPILER_ID.rst
@@ -6,43 +6,60 @@ Compiler identification string.
A short string unique to the compiler vendor. Possible values
include:
-::
-
- Absoft = Absoft Fortran (absoft.com)
- ADSP = Analog VisualDSP++ (analog.com)
- AppleClang = Apple Clang (apple.com)
- ARMCC = ARM Compiler (arm.com)
- ARMClang = ARM Compiler based on Clang (arm.com)
- Bruce = Bruce C Compiler
- CCur = Concurrent Fortran (ccur.com)
- Clang = LLVM Clang (clang.llvm.org)
- Cray = Cray Compiler (cray.com)
- Embarcadero, Borland = Embarcadero (embarcadero.com)
- Flang = Classic Flang Fortran Compiler (https://github.com/flang-compiler/flang)
- LLVMFlang = LLVM Flang Fortran Compiler (https://github.com/llvm/llvm-project/tree/main/flang)
- Fujitsu = Fujitsu HPC compiler (Trad mode)
- FujitsuClang = Fujitsu HPC compiler (Clang mode)
- G95 = G95 Fortran (g95.org)
- GNU = GNU Compiler Collection (gcc.gnu.org)
- GHS = Green Hills Software (www.ghs.com)
- HP = Hewlett-Packard Compiler (hp.com)
- IAR = IAR Systems (iar.com)
- Intel = Intel Compiler (intel.com)
- IntelLLVM = Intel LLVM-Based Compiler (intel.com)
- LCC = MCST Elbrus C/C++/Fortran Compiler (mcst.ru)
- MSVC = Microsoft Visual Studio (microsoft.com)
- NVHPC = NVIDIA HPC SDK Compiler (nvidia.com)
- NVIDIA = NVIDIA CUDA Compiler (nvidia.com)
- OpenWatcom = Open Watcom (openwatcom.org)
- PGI = The Portland Group (pgroup.com)
- PathScale = PathScale (pathscale.com)
- SDCC = Small Device C Compiler (sdcc.sourceforge.net)
- SunPro = Oracle Solaris Studio (oracle.com)
- TI = Texas Instruments (ti.com)
- TinyCC = Tiny C Compiler (tinycc.org)
- XL, VisualAge, zOS = IBM XL (ibm.com)
- XLClang = IBM Clang-based XL (ibm.com)
- IBMClang = IBM LLVM-based Compiler (ibm.com)
+=============================== ===============================================
+Value Name
+=============================== ===============================================
+``Absoft`` `Absoft Fortran`_
+``ADSP`` Analog VisualDSP++
+``AppleClang`` Apple Clang
+``ARMCC`` ARM Compiler
+``ARMClang`` ARM Compiler based on Clang
+``Bruce`` Bruce C Compiler
+``CCur`` Concurrent Fortran
+``Clang`` `LLVM Clang`_
+``Cray`` Cray Compiler
+``Embarcadero``, ``Borland`` `Embarcadero`_
+``Flang`` `Classic Flang Fortran Compiler`_
+``LLVMFlang`` `LLVM Flang Fortran Compiler`_
+``Fujitsu`` Fujitsu HPC compiler (Trad mode)
+``FujitsuClang`` Fujitsu HPC compiler (Clang mode)
+``G95`` `G95 Fortran`_
+``GNU`` `GNU Compiler Collection`_
+``GHS`` `Green Hills Software`_
+``HP`` Hewlett-Packard Compiler
+``IAR`` IAR Systems
+``Intel`` Intel Compiler
+``IntelLLVM`` Intel LLVM-Based Compiler
+``LCC`` MCST Elbrus C/C++/Fortran Compiler
+``MSVC`` `Microsoft Visual Studio`_
+``NVHPC`` `NVIDIA HPC Compiler`_
+``NVIDIA`` `NVIDIA CUDA Compiler`_
+``OpenWatcom`` `Open Watcom`_
+``PGI`` The Portland Group
+``PathScale`` PathScale
+``SDCC`` `Small Device C Compiler`_
+``SunPro`` Oracle Solaris Studio
+``TI`` Texas Instruments
+``TinyCC`` `Tiny C Compiler`_
+``XL``, ``VisualAge``, ``zOS`` IBM XL
+``XLClang`` IBM Clang-based XL
+``IBMClang`` IBM LLVM-based Compiler
+=============================== ===============================================
This variable is not guaranteed to be defined for all compilers or
languages.
+
+.. _Absoft Fortran: https://www.absoft.com
+.. _LLVM Clang: https://clang.llvm.org
+.. _Embarcadero: https://www.embarcadero.com
+.. _Classic Flang Fortran Compiler: https://github.com/flang-compiler/flang
+.. _LLVM Flang Fortran Compiler: https://github.com/llvm/llvm-project/tree/main/flang
+.. _G95 Fortran: http://g95.sourceforge.net
+.. _GNU Compiler Collection: https://gcc.gnu.org
+.. _Green Hills Software: https://www.ghs.com/products/compiler.html
+.. _Microsoft Visual Studio: https://visualstudio.microsoft.com
+.. _NVIDIA HPC Compiler: https://developer.nvidia.com/hpc-compilers
+.. _NVIDIA CUDA Compiler: https://developer.nvidia.com/cuda-llvm-compiler
+.. _Open Watcom: https://open-watcom.github.io
+.. _Small Device C Compiler: http://sdcc.sourceforge.net
+.. _Tiny C Compiler: https://bellard.org/tcc
diff --git a/Help/variable/CMAKE_MAKE_PROGRAM.rst b/Help/variable/CMAKE_MAKE_PROGRAM.rst
index a3c8b7c..9769c7a 100644
--- a/Help/variable/CMAKE_MAKE_PROGRAM.rst
+++ b/Help/variable/CMAKE_MAKE_PROGRAM.rst
@@ -59,6 +59,6 @@ to configure the project:
variable, changing the value has undefined behavior.
The ``CMAKE_MAKE_PROGRAM`` variable is set for use by project code.
-The value is also used by the :manual:`cmake(1)` ``--build`` and
-:manual:`ctest(1)` ``--build-and-test`` tools to launch the native
+The value is also used by the :option:`cmake --build` and
+:option:`ctest --build-and-test` tools to launch the native
build process.
diff --git a/Help/variable/CMAKE_MESSAGE_CONTEXT.rst b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
index 41ace43..7274b7b 100644
--- a/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
+++ b/Help/variable/CMAKE_MESSAGE_CONTEXT.rst
@@ -3,7 +3,7 @@ CMAKE_MESSAGE_CONTEXT
.. versionadded:: 3.17
-When enabled by the :manual:`cmake <cmake(1)>` ``--log-context`` command line
+When enabled by the :option:`cmake --log-context` command line
option or the :variable:`CMAKE_MESSAGE_CONTEXT_SHOW` variable, the
:command:`message` command converts the ``CMAKE_MESSAGE_CONTEXT`` list into a
dot-separated string surrounded by square brackets and prepends it to each line
diff --git a/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
index 3b45d1d..4539c90 100644
--- a/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
+++ b/Help/variable/CMAKE_MESSAGE_LOG_LEVEL.rst
@@ -5,8 +5,9 @@ CMAKE_MESSAGE_LOG_LEVEL
When set, this variable specifies the logging level used by the
:command:`message` command. Valid values are the same as those for the
-``--log-level`` command line option of the :manual:`cmake(1)` program.
-If this variable is set and the ``--log-level`` command line option is
+:option:`--log-level <cmake --log-level>` command line option of the
+:manual:`cmake(1)` program. If this variable is set and the
+:option:`--log-level <cmake --log-level>` command line option is
given, the command line option takes precedence.
The main advantage to using this variable is to make a log level persist
@@ -15,3 +16,8 @@ subsequent CMake runs will continue to use the chosen log level.
Projects should not set this variable, it is intended for users so that
they may control the log level according to their own needs.
+
+.. versionadded:: 3.25
+ See the :command:`cmake_language`
+ :ref:`cmake_language <query_message_log_level>` command for a way to query
+ the current message logging level.
diff --git a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
index 9dce760..f844105 100644
--- a/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
+++ b/Help/variable/CMAKE_POLICY_WARNING_CMPNNNN.rst
@@ -42,5 +42,8 @@ only for the policies that do not warn by default:
This variable should not be set by a project in CMake code. Project
developers running CMake may set this variable in their cache to
enable the warning (e.g. ``-DCMAKE_POLICY_WARNING_CMP<NNNN>=ON``).
-Alternatively, running :manual:`cmake(1)` with the ``--debug-output``,
-``--trace``, or ``--trace-expand`` option will also enable the warning.
+Alternatively, running :manual:`cmake(1)` with the
+:option:`--debug-output <cmake --debug-output>`,
+:option:`--trace <cmake --trace>`, or
+:option:`--trace-expand <cmake --trace-expand>` option will also
+enable the warning.
diff --git a/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst b/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst
index 981af60..104f4ac 100644
--- a/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst
+++ b/Help/variable/CMAKE_SCRIPT_MODE_FILE.rst
@@ -1,9 +1,9 @@
CMAKE_SCRIPT_MODE_FILE
----------------------
-Full path to the :manual:`cmake(1)` ``-P`` script file currently being
+Full path to the :option:`cmake -P <cmake_P -P>` script file currently being
processed.
-When run in :manual:`cmake(1)` ``-P`` script mode, CMake sets this variable to
+When run in :option:`cmake -P <cmake_P -P>` script mode, CMake sets this variable to
the full path of the script file. When run to configure a ``CMakeLists.txt``
file, this variable is not set.
diff --git a/Help/variable/CMAKE_SOURCE_DIR.rst b/Help/variable/CMAKE_SOURCE_DIR.rst
index d1f1798..32e6e90 100644
--- a/Help/variable/CMAKE_SOURCE_DIR.rst
+++ b/Help/variable/CMAKE_SOURCE_DIR.rst
@@ -7,7 +7,7 @@ This is the full path to the top level of the current CMake source
tree. For an in-source build, this would be the same as
:variable:`CMAKE_BINARY_DIR`.
-When run in ``-P`` script mode, CMake sets the variables
+When run in :option:`-P <cmake_P -P>` script mode, CMake sets the variables
:variable:`CMAKE_BINARY_DIR`, :variable:`CMAKE_SOURCE_DIR`,
:variable:`CMAKE_CURRENT_BINARY_DIR` and
:variable:`CMAKE_CURRENT_SOURCE_DIR` to the current working directory.
diff --git a/Help/variable/CMAKE_WARN_DEPRECATED.rst b/Help/variable/CMAKE_WARN_DEPRECATED.rst
index 4a224fa..c7b6159 100644
--- a/Help/variable/CMAKE_WARN_DEPRECATED.rst
+++ b/Help/variable/CMAKE_WARN_DEPRECATED.rst
@@ -7,4 +7,5 @@ If not ``FALSE``, use of deprecated functionality will issue warnings.
If this variable is not set, CMake behaves as if it were set to ``TRUE``.
When running :manual:`cmake(1)`, this option can be enabled with the
-``-Wdeprecated`` option, or disabled with the ``-Wno-deprecated`` option.
+:option:`-Wdeprecated <cmake -Wdeprecated>` option, or disabled with the
+:option:`-Wno-deprecated <cmake -Wno-deprecated>` option.
diff --git a/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst b/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst
index 210da52..6d72d14 100644
--- a/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst
+++ b/Help/variable/CMAKE_XCODE_PLATFORM_TOOLSET.rst
@@ -5,5 +5,5 @@ Xcode compiler selection.
:generator:`Xcode` supports selection of a compiler from one of the installed
toolsets. CMake provides the name of the chosen toolset in this
-variable, if any is explicitly selected (e.g. via the :manual:`cmake(1)`
-``-T`` option).
+variable, if any is explicitly selected (e.g. via the :option:`cmake -T`
+option).
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION.rst b/Help/variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION.rst
new file mode 100644
index 0000000..ce5c4b3
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION.rst
@@ -0,0 +1,13 @@
+CMAKE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION
+--------------------------------------------
+
+.. versionadded:: 3.25
+
+Property value for ``Metal: API Validation`` in the Options section of
+the generated Xcode scheme.
+
+This variable initializes the
+:prop_tgt:`XCODE_SCHEME_ENABLE_GPU_API_VALIDATION` property on all targets.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION.rst b/Help/variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION.rst
new file mode 100644
index 0000000..073a6c9
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION.rst
@@ -0,0 +1,13 @@
+CMAKE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION
+-----------------------------------------------
+
+.. versionadded:: 3.25
+
+Property value for ``Metal: Shader Validation`` in the Options section of
+the generated Xcode scheme.
+
+This variable initializes the
+:prop_tgt:`XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION` property on all targets.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION.rst b/Help/variable/CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION.rst
new file mode 100644
index 0000000..e5b4d18
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION.rst
@@ -0,0 +1,12 @@
+CMAKE_XCODE_SCHEME_LAUNCH_CONFIGURATION
+---------------------------------------
+
+.. versionadded:: 3.25
+
+Set the build configuration to run the target.
+
+This variable initializes the :prop_tgt:`XCODE_SCHEME_LAUNCH_CONFIGURATION`
+property on all targets.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CMAKE_XCODE_SCHEME_LAUNCH_MODE.rst b/Help/variable/CMAKE_XCODE_SCHEME_LAUNCH_MODE.rst
new file mode 100644
index 0000000..c15b1ea
--- /dev/null
+++ b/Help/variable/CMAKE_XCODE_SCHEME_LAUNCH_MODE.rst
@@ -0,0 +1,13 @@
+CMAKE_XCODE_SCHEME_LAUNCH_MODE
+------------------------------
+
+.. versionadded:: 3.25
+
+Property value for ``Launch`` in the Info section of the generated Xcode
+scheme.
+
+This variable initializes the :prop_tgt:`XCODE_SCHEME_LAUNCH_MODE` property on
+all targets.
+
+Please refer to the :prop_tgt:`XCODE_GENERATE_SCHEME` target property
+documentation to see all Xcode schema related properties.
diff --git a/Help/variable/CPACK_CUSTOM_INSTALL_VARIABLES.rst b/Help/variable/CPACK_CUSTOM_INSTALL_VARIABLES.rst
index 1c070b8..9bd50db 100644
--- a/Help/variable/CPACK_CUSTOM_INSTALL_VARIABLES.rst
+++ b/Help/variable/CPACK_CUSTOM_INSTALL_VARIABLES.rst
@@ -3,7 +3,7 @@ CPACK_CUSTOM_INSTALL_VARIABLES
.. versionadded:: 3.21
-CPack variables (set via e.g. ``cpack -D``, ``CPackConfig.cmake`` or
+CPack variables (set via e.g. :option:`cpack -D`, ``CPackConfig.cmake`` or
:variable:`CPACK_PROJECT_CONFIG_FILE` scripts) are not directly visible in
installation scripts. Instead, one can pass a list of ``varName=value``
pairs in the ``CPACK_CUSTOM_INSTALL_VARIABLES`` variable. At install time,
diff --git a/Help/variable/CTEST_CONFIGURATION_TYPE.rst b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
index 392845e..932f81d 100644
--- a/Help/variable/CTEST_CONFIGURATION_TYPE.rst
+++ b/Help/variable/CTEST_CONFIGURATION_TYPE.rst
@@ -6,5 +6,5 @@ CTEST_CONFIGURATION_TYPE
Specify the CTest ``DefaultCTestConfigurationType`` setting
in a :manual:`ctest(1)` dashboard client script.
-If the configuration type is set via ``-C <cfg>`` from the command line
+If the configuration type is set via :option:`-C \<cfg\> <ctest -C>` from the command line
then this variable is populated accordingly.
diff --git a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
index 32c85ad..8cb6eaa 100644
--- a/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
+++ b/Help/variable/CTEST_RUN_CURRENT_SCRIPT.rst
@@ -4,4 +4,4 @@ CTEST_RUN_CURRENT_SCRIPT
.. versionadded:: 3.11
Setting this to 0 prevents :manual:`ctest(1)` from being run again when it
-reaches the end of a script run by calling ``ctest -S``.
+reaches the end of a script run by calling :option:`ctest -S`.
diff --git a/Help/variable/DRAGONFLYBSD.rst b/Help/variable/DRAGONFLYBSD.rst
new file mode 100644
index 0000000..f006156
--- /dev/null
+++ b/Help/variable/DRAGONFLYBSD.rst
@@ -0,0 +1,6 @@
+DRAGONFLYBSD
+------------
+
+.. versionadded:: 3.25
+
+Set to true when the target system is DragonFlyBSD.
diff --git a/Help/variable/FREEBSD.rst b/Help/variable/FREEBSD.rst
new file mode 100644
index 0000000..9990948
--- /dev/null
+++ b/Help/variable/FREEBSD.rst
@@ -0,0 +1,6 @@
+FREEBSD
+-------
+
+.. versionadded:: 3.25
+
+Set to true when the target system is FreeBSD.
diff --git a/Help/variable/LINUX.rst b/Help/variable/LINUX.rst
new file mode 100644
index 0000000..26379b3
--- /dev/null
+++ b/Help/variable/LINUX.rst
@@ -0,0 +1,6 @@
+LINUX
+-----
+
+.. versionadded:: 3.25
+
+Set to true when the target system is Linux.
diff --git a/Help/variable/NETBSD.rst b/Help/variable/NETBSD.rst
new file mode 100644
index 0000000..e7965f8
--- /dev/null
+++ b/Help/variable/NETBSD.rst
@@ -0,0 +1,6 @@
+NETBSD
+------
+
+.. versionadded:: 3.25
+
+Set to true when the target system is NetBSD.
diff --git a/Help/variable/OPENBSD.rst b/Help/variable/OPENBSD.rst
new file mode 100644
index 0000000..dd9b23d
--- /dev/null
+++ b/Help/variable/OPENBSD.rst
@@ -0,0 +1,6 @@
+OPENBSD
+-------
+
+.. versionadded:: 3.25
+
+Set to true when the target system is OpenBSD.
diff --git a/Modules/CMakeDetermineCUDACompiler.cmake b/Modules/CMakeDetermineCUDACompiler.cmake
index 0ac06ac..f43b17b 100644
--- a/Modules/CMakeDetermineCUDACompiler.cmake
+++ b/Modules/CMakeDetermineCUDACompiler.cmake
@@ -275,7 +275,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
if(DEFINED CMAKE_CUDA_ARCHITECTURES)
if(CMAKE_CUDA_ARCHITECTURES STREQUAL "")
message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES must be non-empty if set.")
- elseif(CMAKE_CUDA_ARCHITECTURES AND NOT CMAKE_CUDA_ARCHITECTURES MATCHES "^([0-9]+(-real|-virtual)?(;[0-9]+(-real|-virtual)?|;)*|all|all-major|native)$")
+ elseif(CMAKE_CUDA_ARCHITECTURES AND NOT CMAKE_CUDA_ARCHITECTURES MATCHES "^([0-9]+a?(-real|-virtual)?(;[0-9]+a?(-real|-virtual)?|;)*|all|all-major|native)$")
message(FATAL_ERROR
"CMAKE_CUDA_ARCHITECTURES:\n"
" ${CMAKE_CUDA_ARCHITECTURES}\n"
@@ -503,7 +503,8 @@ elseif(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
CMAKE_CUDA_HOST_IMPLICIT_LINK_DIRECTORIES
CMAKE_CUDA_HOST_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES
log
- "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}")
+ "${CMAKE_CUDA_IMPLICIT_OBJECT_REGEX}"
+ LANGUAGE CUDA)
# Detect CMAKE_CUDA_RUNTIME_LIBRARY_DEFAULT from the compiler by looking at which
# cudart library exists in the implicit link libraries passed to the host linker.
diff --git a/Modules/CMakeDetermineCompileFeatures.cmake b/Modules/CMakeDetermineCompileFeatures.cmake
index a08e597..09de7b1 100644
--- a/Modules/CMakeDetermineCompileFeatures.cmake
+++ b/Modules/CMakeDetermineCompileFeatures.cmake
@@ -63,6 +63,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CXX17_COMPILE_FEATURES)
set(CMAKE_CXX20_COMPILE_FEATURES)
set(CMAKE_CXX23_COMPILE_FEATURES)
+ set(CMAKE_CXX26_COMPILE_FEATURES)
include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
@@ -73,6 +74,9 @@ function(cmake_determine_compile_features lang)
return()
endif()
+ if (CMAKE_CXX23_COMPILE_FEATURES AND CMAKE_CXX26_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CXX26_COMPILE_FEATURES ${CMAKE_CXX23_COMPILE_FEATURES})
+ endif()
if (CMAKE_CXX20_COMPILE_FEATURES AND CMAKE_CXX23_COMPILE_FEATURES)
list(REMOVE_ITEM CMAKE_CXX23_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES})
endif()
@@ -97,6 +101,7 @@ function(cmake_determine_compile_features lang)
${CMAKE_CXX17_COMPILE_FEATURES}
${CMAKE_CXX20_COMPILE_FEATURES}
${CMAKE_CXX23_COMPILE_FEATURES}
+ ${CMAKE_CXX26_COMPILE_FEATURES}
)
endif()
@@ -107,6 +112,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CXX17_COMPILE_FEATURES ${CMAKE_CXX17_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX20_COMPILE_FEATURES ${CMAKE_CXX20_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CXX23_COMPILE_FEATURES ${CMAKE_CXX23_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CXX26_COMPILE_FEATURES ${CMAKE_CXX26_COMPILE_FEATURES} PARENT_SCOPE)
message(CHECK_PASS "done")
@@ -119,6 +125,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CUDA17_COMPILE_FEATURES)
set(CMAKE_CUDA20_COMPILE_FEATURES)
set(CMAKE_CUDA23_COMPILE_FEATURES)
+ set(CMAKE_CUDA26_COMPILE_FEATURES)
include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
@@ -129,6 +136,9 @@ function(cmake_determine_compile_features lang)
return()
endif()
+ if (CMAKE_CUDA23_COMPILE_FEATURES AND CMAKE_CUDA26_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_CUDA26_COMPILE_FEATURES ${CMAKE_CUDA23_COMPILE_FEATURES})
+ endif()
if (CMAKE_CUDA20_COMPILE_FEATURES AND CMAKE_CUDA23_COMPILE_FEATURES)
list(REMOVE_ITEM CMAKE_CUDA23_COMPILE_FEATURES ${CMAKE_CUDA20_COMPILE_FEATURES})
endif()
@@ -153,6 +163,7 @@ function(cmake_determine_compile_features lang)
${CMAKE_CUDA17_COMPILE_FEATURES}
${CMAKE_CUDA20_COMPILE_FEATURES}
${CMAKE_CUDA23_COMPILE_FEATURES}
+ ${CMAKE_CUDA26_COMPILE_FEATURES}
)
endif()
@@ -163,6 +174,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_CUDA17_COMPILE_FEATURES ${CMAKE_CUDA17_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CUDA20_COMPILE_FEATURES ${CMAKE_CUDA20_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_CUDA23_COMPILE_FEATURES ${CMAKE_CUDA23_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_CUDA26_COMPILE_FEATURES ${CMAKE_CUDA26_COMPILE_FEATURES} PARENT_SCOPE)
message(CHECK_PASS "done")
@@ -175,6 +187,8 @@ function(cmake_determine_compile_features lang)
set(CMAKE_HIP17_COMPILE_FEATURES)
set(CMAKE_HIP20_COMPILE_FEATURES)
set(CMAKE_HIP23_COMPILE_FEATURES)
+ set(CMAKE_HIP26_COMPILE_FEATURES)
+
include("${CMAKE_ROOT}/Modules/Internal/FeatureTesting.cmake")
@@ -185,6 +199,9 @@ function(cmake_determine_compile_features lang)
return()
endif()
+ if (CMAKE_HIP23_COMPILE_FEATURES AND CMAKE_HIP26_COMPILE_FEATURES)
+ list(REMOVE_ITEM CMAKE_HIP26_COMPILE_FEATURES ${CMAKE_HIP23_COMPILE_FEATURES})
+ endif()
if (CMAKE_HIP20_COMPILE_FEATURES AND CMAKE_HIP23_COMPILE_FEATURES)
list(REMOVE_ITEM CMAKE_HIP23_COMPILE_FEATURES ${CMAKE_HIP20_COMPILE_FEATURES})
endif()
@@ -209,6 +226,7 @@ function(cmake_determine_compile_features lang)
${CMAKE_HIP17_COMPILE_FEATURES}
${CMAKE_HIP20_COMPILE_FEATURES}
${CMAKE_HIP23_COMPILE_FEATURES}
+ ${CMAKE_HIP26_COMPILE_FEATURES}
)
endif()
@@ -219,6 +237,7 @@ function(cmake_determine_compile_features lang)
set(CMAKE_HIP17_COMPILE_FEATURES ${CMAKE_HIP17_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_HIP20_COMPILE_FEATURES ${CMAKE_HIP20_COMPILE_FEATURES} PARENT_SCOPE)
set(CMAKE_HIP23_COMPILE_FEATURES ${CMAKE_HIP23_COMPILE_FEATURES} PARENT_SCOPE)
+ set(CMAKE_HIP26_COMPILE_FEATURES ${CMAKE_HIP26_COMPILE_FEATURES} PARENT_SCOPE)
message(CHECK_PASS "done")
diff --git a/Modules/CMakeDetermineCompilerABI.cmake b/Modules/CMakeDetermineCompilerABI.cmake
index 82a6d21..69021c1 100644
--- a/Modules/CMakeDetermineCompilerABI.cmake
+++ b/Modules/CMakeDetermineCompilerABI.cmake
@@ -149,7 +149,8 @@ function(CMAKE_DETERMINE_COMPILER_ABI lang src)
if(CMAKE_${lang}_VERBOSE_FLAG)
CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs implicit_fwks log
"${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}"
- COMPUTE_IMPLICIT_OBJECTS implicit_objs)
+ COMPUTE_IMPLICIT_OBJECTS implicit_objs
+ LANGUAGE ${lang})
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Parsed ${lang} implicit link information from above output:\n${log}\n\n")
endif()
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index 2b19736..6b58549 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -720,7 +720,7 @@ Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
OR CMAKE_${lang}_COMPILER_ID_OUTPUT MATCHES "warning #5117: Bad # preprocessor line"
)
# Compilation failed.
- set(MSG
+ string(APPEND _CMAKE_DETERMINE_COMPILER_ID_BUILD_MSG
"Compiling the ${lang} compiler identification source file \"${src}\" failed.
${COMPILER_DESCRIPTION}
The output was:
@@ -736,7 +736,11 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
# Some languages may know the correct/desired set of flags and want to fail right away if they don't work.
# This is currently only used by CUDA.
if(__compiler_id_require_success)
- message(FATAL_ERROR "${MSG}")
+ message(FATAL_ERROR "${_CMAKE_DETERMINE_COMPILER_ID_BUILD_MSG}")
+ else()
+ # Build up the outputs for compiler detection attempts so that users
+ # can see all set of flags tried, instead of just last
+ set(_CMAKE_DETERMINE_COMPILER_ID_BUILD_MSG "${_CMAKE_DETERMINE_COMPILER_ID_BUILD_MSG}" PARENT_SCOPE)
endif()
# No output files should be inspected.
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index 650c87a..087c0f6 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -44,17 +44,14 @@ else()
# finally list compilers to try
if(NOT CMAKE_Fortran_COMPILER_INIT)
# Known compilers:
- # f77/f90/f95: generic compiler names
# ftn: Cray fortran compiler wrapper
- # g77: GNU Fortran 77 compiler
# gfortran: putative GNU Fortran 95+ compiler (in progress)
- # fort77: native F77 compiler under HP-UX (and some older Crays)
- # frt: Fujitsu F77 compiler
+ # frt: Fujitsu Fortran compiler
# pathf90/pathf95/pathf2003: PathScale Fortran compiler
- # pgf77/pgf90/pgf95/pgfortran: Portland Group F77/F90/F95 compilers
+ # pgfortran: Portland Group Fortran compilers
# nvfortran: NVHPC Fotran compiler
# flang: Flang Fortran compiler
- # xlf/xlf90/xlf95: IBM (AIX) F77/F90/F95 compilers
+ # xlf: IBM (AIX) Fortran compiler
# lf95: Lahey-Fujitsu F95 compiler
# fl32: Microsoft Fortran 77 "PowerStation" compiler
# af77: Apogee F77 compiler for Intergraph hardware running CLIX
@@ -62,31 +59,20 @@ else()
# fort: Compaq (now HP) Fortran 90/95 compiler for Tru64 and Linux/Alpha
# ifx: Intel Fortran LLVM-based compiler
# ifort: Intel Classic Fortran compiler
- # ifc: Intel Fortran 95 compiler for Linux/x86
- # efc: Intel Fortran 95 compiler for IA64
# nagfor: NAG Fortran compiler
#
- # The order is 95 or newer compilers first, then 90,
- # then 77 or older compilers, gnu is always last in the group,
+ # GNU is last to be searched,
# so if you paid for a compiler it is picked by default.
- if(CMAKE_HOST_WIN32)
- set(CMAKE_Fortran_COMPILER_LIST
- ifort ifx pgf95 pgfortran nvfortran lf95 fort
- flang gfortran gfortran-4 g95 f90 pgf90
- pgf77 g77 f77 nag
- )
- else()
- set(CMAKE_Fortran_COMPILER_LIST
- ftn
- ifort ifc ifx efc pgf95 pgfortran nvfortran lf95 xlf95 fort
- flang lfortran gfortran gfortran-4 g95 f90 pgf90
- frt pgf77 xlf g77 f77 nag
- )
- endif()
+ set(CMAKE_Fortran_COMPILER_LIST
+ ftn
+ ifx ifort nvfortran pgfortran lf95 xlf fort
+ flang lfortran frt nagfor
+ gfortran
+ )
# Vendor-specific compiler names.
set(_Fortran_COMPILER_NAMES_LCC lfortran gfortran)
- set(_Fortran_COMPILER_NAMES_GNU gfortran gfortran-4 g95 g77)
+ set(_Fortran_COMPILER_NAMES_GNU gfortran)
set(_Fortran_COMPILER_NAMES_Intel ifort ifc efc ifx)
set(_Fortran_COMPILER_NAMES_Absoft af95 af90 af77)
set(_Fortran_COMPILER_NAMES_PGI pgf95 pgfortran pgf90 pgf77)
diff --git a/Modules/CMakeFindFrameworks.cmake b/Modules/CMakeFindFrameworks.cmake
index 8906f48..1aa3929 100644
--- a/Modules/CMakeFindFrameworks.cmake
+++ b/Modules/CMakeFindFrameworks.cmake
@@ -17,12 +17,19 @@ if(NOT CMAKE_FIND_FRAMEWORKS_INCLUDED)
macro(CMAKE_FIND_FRAMEWORKS fwk)
set(${fwk}_FRAMEWORKS)
if(APPLE)
+ # 'Frameworks' directory from Brew (Apple Silicon and Intel)
+ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64")
+ set(_brew_framework_path /opt/homebrew/Frameworks)
+ else()
+ set(_brew_framework_path /usr/local/Frameworks)
+ endif()
+
file(TO_CMAKE_PATH "$ENV{CMAKE_FRAMEWORK_PATH}" _cmff_CMAKE_FRAMEWORK_PATH)
set(_cmff_search_paths
${CMAKE_FRAMEWORK_PATH}
${_cmff_CMAKE_FRAMEWORK_PATH}
~/Library/Frameworks
- /usr/local/Frameworks
+ ${_brew_framework_path}
/Library/Frameworks
/System/Library/Frameworks
/Network/Library/Frameworks
diff --git a/Modules/CMakeParseImplicitLinkInfo.cmake b/Modules/CMakeParseImplicitLinkInfo.cmake
index 6bdefde..1773dc4 100644
--- a/Modules/CMakeParseImplicitLinkInfo.cmake
+++ b/Modules/CMakeParseImplicitLinkInfo.cmake
@@ -22,7 +22,7 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
set(log "")
set(keywordArgs)
- set(oneValueArgs COMPUTE_IMPLICIT_OBJECTS)
+ set(oneValueArgs COMPUTE_IMPLICIT_OBJECTS LANGUAGE)
set(multiValueArgs )
cmake_parse_arguments(EXTRA_PARSE "${keywordArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
@@ -76,6 +76,11 @@ function(CMAKE_PARSE_IMPLICIT_LINK_INFO text lib_var dir_var fwk_var log_var obj
endif()
endif()
set(is_msvc 0)
+ if(EXTRA_PARSE_LANGUAGE AND
+ ("x${CMAKE_${EXTRA_PARSE_LANGUAGE}_ID}" STREQUAL "xMSVC" OR
+ "x${CMAKE_${EXTRA_PARSE_LANGUAGE}_SIMULATE_ID}" STREQUAL "xMSVC"))
+ set(is_msvc 1)
+ endif()
set(search_static 0)
if("${cmd}" MATCHES "${linker_regex}")
string(APPEND log " link line: [${line}]\n")
diff --git a/Modules/CMakeSwiftInformation.cmake b/Modules/CMakeSwiftInformation.cmake
index ecad1d5..16726d2 100644
--- a/Modules/CMakeSwiftInformation.cmake
+++ b/Modules/CMakeSwiftInformation.cmake
@@ -65,7 +65,7 @@ set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDLL -libc MD)
set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebug -libc MTd)
set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY_MultiThreadedDebugDLL -libc MDd)
-set(CMAKE_Swift_FLAGS_DEBUG_INIT "-g")
+set(CMAKE_Swift_FLAGS_DEBUG_INIT "-Onone -g")
set(CMAKE_Swift_FLAGS_RELEASE_INIT "-O")
set(CMAKE_Swift_FLAGS_RELWITHDEBINFO_INIT "-O -g")
set(CMAKE_Swift_FLAGS_MINSIZEREL_INIT "-Osize")
diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake
index 853d655..a6d0f8b 100644
--- a/Modules/CMakeTestCUDACompiler.cmake
+++ b/Modules/CMakeTestCUDACompiler.cmake
@@ -126,10 +126,8 @@ list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_LINK_LIBRARIES ${CMAKE_CUDA_IMPLICIT_LINK_L
if(CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA")
# Remove the CUDA Toolkit include directories from the set of
# implicit system include directories.
- # This resolves the issue that NVCC doesn't specify these
- # includes as SYSTEM includes when compiling device code, and sometimes
- # they contain headers that generate warnings, so let users mark them
- # as SYSTEM explicitly
+ # CMake will explicitly mark these as SYSTEM to NVCC since it implicitly
+ # adds them as user includes and not system
if(CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES)
list(REMOVE_ITEM CMAKE_CUDA_IMPLICIT_INCLUDE_DIRECTORIES
${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake
index 4934934..828d9ca 100644
--- a/Modules/CPack.cmake
+++ b/Modules/CPack.cmake
@@ -53,9 +53,9 @@ Here's how it works:
* :manual:`cpack <cpack(1)>` runs
* it includes ``CPackConfig.cmake``
-* it iterates over the generators given by the ``-G`` command line option,
- or if no such option was specified, over the list of generators given by
- the :variable:`CPACK_GENERATOR` variable set in the ``CPackConfig.cmake``
+* it iterates over the generators given by the :option:`-G <cpack -G>` command
+ line option, or if no such option was specified, over the list of generators
+ given by the :variable:`CPACK_GENERATOR` variable set in the ``CPackConfig.cmake``
input file.
* foreach generator, it then
@@ -246,9 +246,9 @@ installers. The most commonly-used variables are:
List of CPack generators to use. If not specified, CPack will create a
set of options following the naming pattern
:variable:`CPACK_BINARY_<GENNAME>` (e.g. ``CPACK_BINARY_NSIS``) allowing
- the user to enable/disable individual generators. If the ``-G`` option is
- given on the :manual:`cpack <cpack(1)>` command line, it will override this
- variable and any ``CPACK_BINARY_<GENNAME>`` options.
+ the user to enable/disable individual generators. If the :option:`-G <cpack -G>`
+ option is given on the :manual:`cpack <cpack(1)>` command line, it will override
+ this variable and any ``CPACK_BINARY_<GENNAME>`` options.
.. variable:: CPACK_OUTPUT_CONFIG_FILE
@@ -469,7 +469,35 @@ The following variables are for advanced uses of CPack:
generates (when :variable:`CPACK_GENERATOR` is not set) a set of CMake
options (see CMake :command:`option` command) which may then be used to
select the CPack generator(s) to be used when building the ``package``
- target or when running :manual:`cpack <cpack(1)>` without the ``-G`` option.
+ target or when running :manual:`cpack <cpack(1)>` without the
+ :option:`-G <cpack -G>` option.
+
+.. variable:: CPACK_READELF_EXECUTABLE
+
+ .. versionadded:: 3.25
+
+ Specify the ``readelf`` executable path used by CPack.
+ The default value will be ``CMAKE_READELF`` when set. Otherwise,
+ the default value will be empty and CPack will use :command:`find_program`
+ to determine the ``readelf`` path when needed.
+
+.. variable:: CPACK_OBJCOPY_EXECUTABLE
+
+ .. versionadded:: 3.25
+
+ Specify the ``objcopy`` executable path used by CPack.
+ The default value will be ``CMAKE_OBJCOPY`` when set. Otherwise,
+ the default value will be empty and CPack will use :command:`find_program`
+ to determine the ``objcopy`` path when needed.
+
+.. variable:: CPACK_OBJDUMP_EXECUTABLE
+
+ .. versionadded:: 3.25
+
+ Specify the ``objdump`` executable path used by CPack.
+ The default value will be ``CMAKE_OBJDUMP`` when set. Otherwise,
+ the default value will be empty and CPack will use :command:`find_program`
+ to determine the ``objdump`` path when needed.
#]=======================================================================]
@@ -590,6 +618,16 @@ _cpack_set_default(CPACK_RESOURCE_FILE_WELCOME
_cpack_set_default(CPACK_MODULE_PATH "${CMAKE_MODULE_PATH}")
+if(CMAKE_READELF)
+ _cpack_set_default(CPACK_READELF_EXECUTABLE "${CMAKE_READELF}")
+endif()
+if(CMAKE_OBJCOPY)
+ _cpack_set_default(CPACK_OBJCOPY_EXECUTABLE "${CMAKE_OBJCOPY}")
+endif()
+if(CMAKE_OBJDUMP)
+ _cpack_set_default(CPACK_OBJDUMP_EXECUTABLE "${CMAKE_OBJDUMP}")
+endif()
+
# Set default directory creation permissions mode
if(CMAKE_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS)
_cpack_set_default(CPACK_INSTALL_DEFAULT_DIRECTORY_PERMISSIONS
diff --git a/Modules/CTestTargets.cmake b/Modules/CTestTargets.cmake
index 838fbbf..b91b48e 100644
--- a/Modules/CTestTargets.cmake
+++ b/Modules/CTestTargets.cmake
@@ -86,7 +86,7 @@ if(NOT _CTEST_TARGETS_ADDED)
# or "RUN_TESTS" target:
if(CTEST_TEST_TARGET_ALIAS)
add_custom_target(${CTEST_TEST_TARGET_ALIAS}
- ${CMAKE_CTEST_COMMAND} ${__conf_types}
+ ${CMAKE_CTEST_COMMAND} ${CMAKE_CTEST_ARGUMENTS} ${__conf_types}
USES_TERMINAL
)
endif()
diff --git a/Modules/CTestUseLaunchers.cmake b/Modules/CTestUseLaunchers.cmake
index 23a206b..5c544f8 100644
--- a/Modules/CTestUseLaunchers.cmake
+++ b/Modules/CTestUseLaunchers.cmake
@@ -11,7 +11,7 @@ CTestUseLaunchers is automatically included when you include(CTest).
However, it is split out into its own module file so projects can use
the CTEST_USE_LAUNCHERS functionality independently.
-To use launchers, set CTEST_USE_LAUNCHERS to ON in a ctest -S
+To use launchers, set CTEST_USE_LAUNCHERS to ON in a :option:`ctest -S`
dashboard script, and then also set it in the cache of the configured
project. Both cmake and ctest need to know the value of it for the
launchers to work properly. CMake needs to know in order to generate
@@ -27,9 +27,12 @@ variable initialization only occurs if CTEST_USE_LAUNCHERS is not
already defined.
.. versionadded:: 3.8
- If CTEST_USE_LAUNCHERS is on in a ctest -S script
+ If CTEST_USE_LAUNCHERS is on in a :option:`ctest -S` script
the ctest_configure command will add -DCTEST_USE_LAUNCHERS:BOOL=TRUE
to the cmake command used to configure the project.
+
+.. TODO Use RST markup
+
#]=======================================================================]
if(NOT DEFINED CTEST_USE_LAUNCHERS AND DEFINED ENV{CTEST_USE_LAUNCHERS_DEFAULT})
diff --git a/Modules/CheckIPOSupported.cmake b/Modules/CheckIPOSupported.cmake
index cca1be9..14262a1 100644
--- a/Modules/CheckIPOSupported.cmake
+++ b/Modules/CheckIPOSupported.cmake
@@ -76,6 +76,23 @@ endmacro()
# Run IPO/LTO test
macro(_ipo_run_language_check language)
+ set(_C_ext "c")
+ set(_CXX_ext "cpp")
+ set(_Fortran_ext "f")
+ string(COMPARE EQUAL "${language}" "CUDA" is_cuda)
+
+ set(ext ${_${language}_ext})
+ if(NOT "${ext}" STREQUAL "")
+ set(copy_sources foo.${ext} main.${ext})
+ elseif(is_cuda)
+ if(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE)
+ set("${X_RESULT}" YES PARENT_SCOPE)
+ endif()
+ return()
+ else()
+ message(FATAL_ERROR "Language not supported")
+ endif()
+
set(testdir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/_CMakeLTOTest-${language}")
file(REMOVE_RECURSE "${testdir}")
@@ -100,20 +117,6 @@ macro(_ipo_run_language_check language)
@ONLY
)
- string(COMPARE EQUAL "${language}" "C" is_c)
- string(COMPARE EQUAL "${language}" "CXX" is_cxx)
- string(COMPARE EQUAL "${language}" "Fortran" is_fortran)
-
- if(is_c)
- set(copy_sources foo.c main.c)
- elseif(is_cxx)
- set(copy_sources foo.cpp main.cpp)
- elseif(is_fortran)
- set(copy_sources foo.f main.f)
- else()
- message(FATAL_ERROR "Language not supported")
- endif()
-
foreach(x ${copy_sources})
configure_file(
"${try_compile_src}/${x}"
@@ -214,6 +217,11 @@ function(check_ipo_supported)
list(APPEND languages "C")
endif()
+ list(FIND enabled_languages "CUDA" result)
+ if(NOT result EQUAL -1)
+ list(APPEND languages "CUDA")
+ endif()
+
list(FIND enabled_languages "Fortran" result)
if(NOT result EQUAL -1)
list(APPEND languages "Fortran")
@@ -222,7 +230,7 @@ function(check_ipo_supported)
string(COMPARE EQUAL "${languages}" "" no_languages)
if(no_languages)
_ipo_not_supported(
- "no C/CXX/Fortran languages found in ENABLED_LANGUAGES global property"
+ "no C/CXX/CUDA/Fortran languages found in ENABLED_LANGUAGES global property"
)
return()
endif()
@@ -230,7 +238,7 @@ function(check_ipo_supported)
set(languages "${X_LANGUAGES}")
set(unsupported_languages "${languages}")
- list(REMOVE_ITEM unsupported_languages "C" "CXX" "Fortran")
+ list(REMOVE_ITEM unsupported_languages "C" "CXX" "CUDA" "Fortran")
string(COMPARE NOTEQUAL "${unsupported_languages}" "" has_unsupported)
if(has_unsupported)
_ipo_not_supported(
diff --git a/Modules/Compiler/Clang-CUDA.cmake b/Modules/Compiler/Clang-CUDA.cmake
index 219897e..d9929f1 100644
--- a/Modules/Compiler/Clang-CUDA.cmake
+++ b/Modules/Compiler/Clang-CUDA.cmake
@@ -35,6 +35,10 @@ set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static")
set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart")
set(CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_NONE "")
+# Clang doesn't support CUDA device LTO
+set(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE NO)
+set(_CMAKE_CUDA_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
+
if(UNIX)
list(APPEND CMAKE_CUDA_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "rt" "pthread" "dl")
endif()
diff --git a/Modules/Compiler/Clang.cmake b/Modules/Compiler/Clang.cmake
index df115d3..257402a 100644
--- a/Modules/Compiler/Clang.cmake
+++ b/Modules/Compiler/Clang.cmake
@@ -255,6 +255,7 @@ macro(__compiler_clang_cxx_standards lang)
cxx_std_17
cxx_std_20
cxx_std_23
+ cxx_std_26
)
_record_compiler_features(${lang} "" CMAKE_${lang}_COMPILE_FEATURES)
endmacro()
diff --git a/Modules/Compiler/IntelLLVM-FindBinUtils.cmake b/Modules/Compiler/IntelLLVM-FindBinUtils.cmake
new file mode 100644
index 0000000..c5b1ee6
--- /dev/null
+++ b/Modules/Compiler/IntelLLVM-FindBinUtils.cmake
@@ -0,0 +1,45 @@
+if(NOT DEFINED _CMAKE_PROCESSING_LANGUAGE OR _CMAKE_PROCESSING_LANGUAGE STREQUAL "")
+ message(FATAL_ERROR "Internal error: _CMAKE_PROCESSING_LANGUAGE is not set")
+endif()
+
+# Ubuntu:
+# * /usr/bin/llvm-ar-9
+# * /usr/bin/llvm-ranlib-9
+string(REGEX MATCH "^([0-9]+)" __version_x
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}")
+
+# Debian:
+# * /usr/bin/llvm-ar-4.0
+# * /usr/bin/llvm-ranlib-4.0
+string(REGEX MATCH "^([0-9]+\\.[0-9]+)" __version_x_y
+ "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_VERSION}")
+
+# Try to find tools in the IntelLLVM Clang tools directory
+get_filename_component(__intel_llvm_hint_1 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
+get_filename_component(__intel_llvm_hint_1 "${__intel_llvm_hint_1}/../bin-llvm" REALPATH)
+
+get_filename_component(__intel_llvm_hint_2 "${CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER}" DIRECTORY)
+
+set(__intel_llvm_hints ${__intel_llvm_hint_1} ${__intel_llvm_hint_2})
+
+# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ar.1.html
+find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR NAMES
+ "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar-${__version_x_y}"
+ "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar-${__version_x}"
+ "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ar"
+ HINTS ${__intel_llvm_hints}
+ NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH
+ DOC "LLVM archiver"
+)
+mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_AR)
+
+# http://manpages.ubuntu.com/manpages/precise/en/man1/llvm-ranlib.1.html
+find_program(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB NAMES
+ "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib-${__version_x_y}"
+ "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib-${__version_x}"
+ "${_CMAKE_TOOLCHAIN_PREFIX}llvm-ranlib"
+ HINTS ${__intel_llvm_hints}
+ NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH
+ DOC "Generate index for LLVM archive"
+)
+mark_as_advanced(CMAKE_${_CMAKE_PROCESSING_LANGUAGE}_COMPILER_RANLIB)
diff --git a/Modules/Compiler/IntelLLVM.cmake b/Modules/Compiler/IntelLLVM.cmake
index c344f32..3f22efd 100644
--- a/Modules/Compiler/IntelLLVM.cmake
+++ b/Modules/Compiler/IntelLLVM.cmake
@@ -15,6 +15,15 @@ set(__pch_header_CXX "c++-header")
set(__pch_header_OBJC "objective-c-header")
set(__pch_header_OBJCXX "objective-c++-header")
+# Variables that are common across front-end variants
+macro(__compiler_intel_llvm_common lang)
+ set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
+ set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+ set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" cr <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" r <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_${lang}_ARCHIVE_FINISH_IPO "\"${CMAKE_${lang}_COMPILER_RANLIB}\" <TARGET>")
+endmacro()
+
if(CMAKE_HOST_WIN32)
# MSVC-like
macro(__compiler_intel_llvm lang)
@@ -22,6 +31,9 @@ if(CMAKE_HOST_WIN32)
set(CMAKE_${lang}_COMPILE_OPTIONS_INVALID_PCH -Winvalid-pch)
set(CMAKE_${lang}_COMPILE_OPTIONS_WARNING_AS_ERROR "-WX")
endif()
+ __compiler_intel_llvm_common(${lang})
+ set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-Qipo")
+ set(CMAKE_${lang}_LINK_OPTIONS_IPO "-Qipo")
endmacro()
else()
# GNU-like
@@ -60,12 +72,9 @@ else()
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Xlinker" " ")
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP)
- set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
- set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
- set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-flto=thin")
- set(CMAKE_${lang}_ARCHIVE_CREATE_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" cr <TARGET> <LINK_FLAGS> <OBJECTS>")
- set(CMAKE_${lang}_ARCHIVE_APPEND_IPO "\"${CMAKE_${lang}_COMPILER_AR}\" r <TARGET> <LINK_FLAGS> <OBJECTS>")
- set(CMAKE_${lang}_ARCHIVE_FINISH_IPO "\"${CMAKE_${lang}_COMPILER_RANLIB}\" <TARGET>")
+ __compiler_intel_llvm_common(${lang})
+ set(CMAKE_${lang}_COMPILE_OPTIONS_IPO "-ipo")
+ set(CMAKE_${lang}_LINK_OPTIONS_IPO "-ipo")
set(CMAKE_${lang}_CREATE_PREPROCESSED_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -E <SOURCE> > <PREPROCESSED_SOURCE>")
set(CMAKE_${lang}_CREATE_ASSEMBLY_SOURCE "<CMAKE_${lang}_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -S <SOURCE> -o <ASSEMBLY_SOURCE>")
diff --git a/Modules/Compiler/MSVC-CXX.cmake b/Modules/Compiler/MSVC-CXX.cmake
index 75165fd..60d13f1 100644
--- a/Modules/Compiler/MSVC-CXX.cmake
+++ b/Modules/Compiler/MSVC-CXX.cmake
@@ -72,6 +72,7 @@ elseif (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 16.0)
cxx_std_17
cxx_std_20
cxx_std_23
+ cxx_std_26
)
_record_compiler_features(CXX "" CMAKE_CXX_COMPILE_FEATURES)
endmacro()
diff --git a/Modules/Compiler/NVIDIA-CUDA.cmake b/Modules/Compiler/NVIDIA-CUDA.cmake
index 2e3ae2c..2b8a1ea 100644
--- a/Modules/Compiler/NVIDIA-CUDA.cmake
+++ b/Modules/Compiler/NVIDIA-CUDA.cmake
@@ -48,6 +48,13 @@ if((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
set(CMAKE_CUDA_DEPENDS_USE_COMPILER TRUE)
endif()
+if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.2)
+ set(_CMAKE_CUDA_IPO_SUPPORTED_BY_CMAKE YES)
+ set(_CMAKE_CUDA_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
+
+ set(CMAKE_CUDA_DEVICE_LINK_OPTIONS_IPO " -dlto")
+endif()
+
if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
set(CMAKE_CUDA_COMPILE_OPTIONS_PIE -Xcompiler=-fPIE)
set(CMAKE_CUDA_COMPILE_OPTIONS_PIC -Xcompiler=-fPIC)
@@ -61,6 +68,7 @@ if(NOT "x${CMAKE_CUDA_SIMULATE_ID}" STREQUAL "xMSVC")
string(APPEND CMAKE_CUDA_FLAGS_MINSIZEREL_INIT " -O1 -DNDEBUG")
string(APPEND CMAKE_CUDA_FLAGS_RELWITHDEBINFO_INIT " -O2 -g -DNDEBUG")
endif()
+
set(CMAKE_SHARED_LIBRARY_CREATE_CUDA_FLAGS -shared)
set(CMAKE_INCLUDE_SYSTEM_FLAG_CUDA -isystem=)
@@ -132,15 +140,19 @@ else()
endif()
-# FIXME: investigate use of --options-file.
-# Tell Makefile generator that nvcc does not support @<rspfile> syntax.
-set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0)
-set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
-set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0)
-
if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "9.0")
set(CMAKE_CUDA_RESPONSE_FILE_DEVICE_LINK_FLAG "--options-file ")
set(CMAKE_CUDA_RESPONSE_FILE_FLAG "--options-file ")
endif()
+if (CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL "11.0")
+ set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 1)
+ set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 1)
+ set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 1)
+else()
+ set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES 0)
+ set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES 0)
+ set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS 0)
+endif()
+
__compiler_check_default_language_standard(CUDA 6.0 03)
diff --git a/Modules/ExternalProject.cmake b/Modules/ExternalProject.cmake
index 9952658..9306ce6 100644
--- a/Modules/ExternalProject.cmake
+++ b/Modules/ExternalProject.cmake
@@ -3832,6 +3832,19 @@ function(_ep_add_install_command name)
set(uses_terminal "")
endif()
+ # With BUILD_ALWAYS+BUILD_BYPRODUCTS, Ninja restats the
+ # build step outputs and may not consider this step to
+ # be out-of-date. Explicitly mark it out-of-date too.
+ get_property(build_always
+ TARGET ${name}
+ PROPERTY _EP_BUILD_ALWAYS
+ )
+ if(build_always)
+ set(always 1)
+ else()
+ set(always 0)
+ endif()
+
set(__cmdQuoted)
foreach(__item IN LISTS cmd)
string(APPEND __cmdQuoted " [==[${__item}]==]")
@@ -3842,6 +3855,7 @@ function(_ep_add_install_command name)
COMMAND ${__cmdQuoted}
WORKING_DIRECTORY \${binary_dir}
DEPENDEES build
+ ALWAYS \${always}
${log}
${uses_terminal}
)"
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 20f0bd2..e5a272c 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -881,9 +881,10 @@ Overriding Where To Find CMakeLists.txt
If the sub-project's ``CMakeLists.txt`` file is not at the top level of its
source tree, the ``SOURCE_SUBDIR`` option can be used to tell ``FetchContent``
-where to find it. The following example shows how to use that option and
+where to find it. The following example shows how to use that option, and
it also sets a variable which is meaningful to the subproject before pulling
-it into the main build:
+it into the main build (set as an ``INTERNAL`` cache variable to avoid
+problems with policy :policy:`CMP0077`):
.. code-block:: cmake
@@ -894,7 +895,7 @@ it into the main build:
GIT_TAG ae50d9b9902526efd6c7a1907d09739f959c6297 # v3.15.0
SOURCE_SUBDIR cmake
)
- set(protobuf_BUILD_TESTS OFF)
+ set(protobuf_BUILD_TESTS OFF CACHE INTERNAL "")
FetchContent_MakeAvailable(protobuf)
Complex Dependency Hierarchies
diff --git a/Modules/FindBLAS.cmake b/Modules/FindBLAS.cmake
index 7a381af..d02c589 100644
--- a/Modules/FindBLAS.cmake
+++ b/Modules/FindBLAS.cmake
@@ -35,6 +35,12 @@ The following variables may be set to influence this module's behavior:
if set ``pkg-config`` will be used to search for a BLAS library first
and if one is found that is preferred
+``BLA_PKGCONFIG_BLAS``
+ .. versionadded:: 3.25
+
+ If set, the ``pkg-config`` method will look for this module name instead of
+ just ``blas``.
+
``BLA_SIZEOF_INTEGER``
.. versionadded:: 3.22
@@ -273,8 +279,11 @@ endif()
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
if(BLA_PREFER_PKGCONFIG)
+ if(NOT BLA_PKGCONFIG_BLAS)
+ set(BLA_PKGCONFIG_BLAS "blas")
+ endif()
find_package(PkgConfig QUIET)
- pkg_check_modules(PKGC_BLAS QUIET blas)
+ pkg_check_modules(PKGC_BLAS QUIET ${BLA_PKGCONFIG_BLAS})
if(PKGC_BLAS_FOUND)
set(BLAS_FOUND ${PKGC_BLAS_FOUND})
set(BLAS_LIBRARIES "${PKGC_BLAS_LINK_LIBRARIES}")
diff --git a/Modules/FindCUDA.cmake b/Modules/FindCUDA.cmake
index af5f798..470111f 100644
--- a/Modules/FindCUDA.cmake
+++ b/Modules/FindCUDA.cmake
@@ -799,7 +799,9 @@ if(NOT "${CUDA_TOOLKIT_ROOT_DIR}" STREQUAL "${CUDA_TOOLKIT_ROOT_DIR_INTERNAL}")
unset(CUDA_VERSION CACHE)
endif()
-if(NOT "${CUDA_TOOLKIT_TARGET_DIR}" STREQUAL "${CUDA_TOOLKIT_TARGET_DIR_INTERNAL}")
+# If CUDA_TOOLKIT_TARGET_DIR exists, check if it has changed.
+if(DEFINED CUDA_TOOLKIT_TARGET_DIR
+ AND NOT "${CUDA_TOOLKIT_TARGET_DIR}" STREQUAL "${CUDA_TOOLKIT_TARGET_DIR_INTERNAL}")
cuda_unset_include_and_libraries()
endif()
diff --git a/Modules/FindCUDAToolkit.cmake b/Modules/FindCUDAToolkit.cmake
index 5f83ccc..0e333cc 100644
--- a/Modules/FindCUDAToolkit.cmake
+++ b/Modules/FindCUDAToolkit.cmake
@@ -121,6 +121,7 @@ of the following libraries that are part of the CUDAToolkit:
- :ref:`nvidia-ML<cuda_toolkit_nvML>`
- :ref:`nvRTC<cuda_toolkit_nvRTC>`
- :ref:`nvToolsExt<cuda_toolkit_nvToolsExt>`
+- :ref:`nvtx3<cuda_toolkit_nvtx3>`
- :ref:`OpenCL<cuda_toolkit_opencl>`
- :ref:`cuLIBOS<cuda_toolkit_cuLIBOS>`
@@ -362,6 +363,8 @@ Targets Created:
nvToolsExt
""""""""""
+.. deprecated:: 3.25 With CUDA 10.0+, use :ref:`nvtx3 <cuda_toolkit_nvtx3>`.
+
The `NVIDIA Tools Extension <https://docs.nvidia.com/gameworks/content/gameworkslibrary/nvtx/nvidia_tools_extension_library_nvtx.htm>`_.
This is a shared library only.
@@ -369,6 +372,20 @@ Targets Created:
- ``CUDA::nvToolsExt``
+.. _`cuda_toolkit_nvtx3`:
+
+nvtx3
+"""""
+
+.. versionadded:: 3.25
+
+The header-only `NVIDIA Tools Extension Library <https://nvidia.github.io/NVTX/doxygen/index.html>`_.
+Introduced in CUDA 10.0.
+
+Targets created:
+
+- ``CUDA::nvtx3``
+
.. _`cuda_toolkit_opencl`:
OpenCL
@@ -1014,6 +1031,21 @@ if(CUDAToolkit_FOUND)
endif()
_CUDAToolkit_find_and_add_import_lib(nvToolsExt ALT nvToolsExt64)
+ if(CUDAToolkit_VERSION VERSION_GREATER_EQUAL 10.0)
+ # nvToolsExt is deprecated since nvtx3 introduction.
+ # Warn only if the project requires a sufficiently new CMake to make migration possible.
+ if(CMAKE_MINIMUM_REQUIRED_VERSION VERSION_GREATER_EQUAL 3.25)
+ set_property(TARGET CUDA::nvToolsExt PROPERTY DEPRECATION "nvToolsExt has been superseded by nvtx3 since CUDA 10.0 and CMake 3.25. Use CUDA::nvtx3 and include <nvtx3/nvToolsExt.h> instead.")
+ endif()
+
+ # Header-only variant. Uses dlopen().
+ if(NOT TARGET CUDA::nvtx3)
+ add_library(CUDA::nvtx3 INTERFACE IMPORTED)
+ target_include_directories(CUDA::nvtx3 SYSTEM INTERFACE "${CUDAToolkit_INCLUDE_DIRS}")
+ target_link_libraries(CUDA::nvtx3 INTERFACE ${CMAKE_DL_LIBS})
+ endif()
+ endif()
+
_CUDAToolkit_find_and_add_import_lib(OpenCL)
endif()
diff --git a/Modules/FindCURL.cmake b/Modules/FindCURL.cmake
index e37d225..acb87dc 100644
--- a/Modules/FindCURL.cmake
+++ b/Modules/FindCURL.cmake
@@ -72,6 +72,8 @@ if(NOT CURL_NO_CURL_CMAKE)
# can print what we found and return.
if(CURL_FOUND)
find_package_handle_standard_args(CURL HANDLE_COMPONENTS CONFIG_MODE)
+ # The upstream curl package sets CURL_VERSION, not CURL_VERSION_STRING.
+ set(CURL_VERSION_STRING "${CURL_VERSION}")
return()
endif()
endif()
@@ -80,7 +82,6 @@ find_package(PkgConfig QUIET)
if(PKG_CONFIG_FOUND)
pkg_check_modules(PC_CURL QUIET libcurl)
if(PC_CURL_FOUND)
- set(CURL_VERSION_STRING ${PC_CURL_VERSION})
pkg_get_variable(CURL_SUPPORTED_PROTOCOLS libcurl supported_protocols)
pkg_get_variable(CURL_SUPPORTED_FEATURES libcurl supported_features)
endif()
@@ -120,7 +121,7 @@ if(NOT CURL_LIBRARY)
select_library_configurations(CURL)
endif()
-if(CURL_INCLUDE_DIR AND NOT CURL_VERSION_STRING)
+if(CURL_INCLUDE_DIR)
foreach(_curl_version_header curlver.h curl.h)
if(EXISTS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}")
file(STRINGS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}" curl_version_str REGEX "^#define[\t ]+LIBCURL_VERSION[\t ]+\".*\"")
diff --git a/Modules/FindCoin3D.cmake b/Modules/FindCoin3D.cmake
index 301e70b..5910ad1 100644
--- a/Modules/FindCoin3D.cmake
+++ b/Modules/FindCoin3D.cmake
@@ -31,11 +31,11 @@ if (WIN32)
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/include"
)
- find_library(COIN3D_LIBRARY_DEBUG coin2d
+ find_library(COIN3D_LIBRARY_DEBUG NAMES coin2d coin4d
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/lib"
)
- find_library(COIN3D_LIBRARY_RELEASE coin2
+ find_library(COIN3D_LIBRARY_RELEASE NAMES coin2 coin4
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\SIM\\Coin3D\\2;Installation Path]/lib"
)
diff --git a/Modules/FindDoxygen.cmake b/Modules/FindDoxygen.cmake
index 4a16e31..23b7107 100644
--- a/Modules/FindDoxygen.cmake
+++ b/Modules/FindDoxygen.cmake
@@ -432,9 +432,44 @@ endif()
# or use something like homebrew.
# ============== End OSX stuff ================
+include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+
#
# Find Doxygen...
#
+function(_Doxygen_get_version doxy_version result_var doxy_path)
+ execute_process(
+ COMMAND "${doxy_path}" --version
+ OUTPUT_VARIABLE full_doxygen_version
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE version_result
+ )
+
+ # Ignore any commit hashes, etc.
+ string(REGEX MATCH [[^[0-9]+\.[0-9]+\.[0-9]+]] sem_doxygen_version "${full_doxygen_version}")
+
+ set(${result_var} ${version_result} PARENT_SCOPE)
+ set(${doxy_version} ${sem_doxygen_version} PARENT_SCOPE)
+endfunction()
+
+function(_Doxygen_version_validator version_match doxy_path)
+ if(NOT DEFINED Doxygen_FIND_VERSION)
+ set(${is_valid_version} TRUE PARENT_SCOPE)
+ else()
+ _Doxygen_get_version(candidate_version version_result "${doxy_path}")
+
+ if(version_result)
+ message(DEBUG "Unable to determine candidate doxygen version at ${doxy_path}: ${version_result}")
+ endif()
+
+ find_package_check_version("${candidate_version}" valid_doxy_version
+ HANDLE_VERSION_RANGE
+ )
+
+ set(${version_match} "${valid_doxy_version}" PARENT_SCOPE)
+ endif()
+endfunction()
+
macro(_Doxygen_find_doxygen)
find_program(
DOXYGEN_EXECUTABLE
@@ -446,16 +481,13 @@ macro(_Doxygen_find_doxygen)
/Applications/Utilities/Doxygen.app/Contents/Resources
/Applications/Utilities/Doxygen.app/Contents/MacOS
DOC "Doxygen documentation generation tool (http://www.doxygen.org)"
+ VALIDATOR _Doxygen_version_validator
)
mark_as_advanced(DOXYGEN_EXECUTABLE)
if(DOXYGEN_EXECUTABLE)
- execute_process(
- COMMAND "${DOXYGEN_EXECUTABLE}" --version
- OUTPUT_VARIABLE DOXYGEN_VERSION
- OUTPUT_STRIP_TRAILING_WHITESPACE
- RESULT_VARIABLE _Doxygen_version_result
- )
+ _Doxygen_get_version(DOXYGEN_VERSION _Doxygen_version_result "${DOXYGEN_EXECUTABLE}")
+
if(_Doxygen_version_result)
message(WARNING "Unable to determine doxygen version: ${_Doxygen_version_result}")
endif()
@@ -642,11 +674,11 @@ endforeach()
unset(_comp)
# Verify find results
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
find_package_handle_standard_args(
Doxygen
REQUIRED_VARS DOXYGEN_EXECUTABLE
VERSION_VAR DOXYGEN_VERSION
+ HANDLE_VERSION_RANGE
HANDLE_COMPONENTS
)
diff --git a/Modules/FindGLEW.cmake b/Modules/FindGLEW.cmake
index b9ebe08..bfde40b 100644
--- a/Modules/FindGLEW.cmake
+++ b/Modules/FindGLEW.cmake
@@ -63,11 +63,36 @@ This module defines the following variables:
#]=======================================================================]
include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
find_package(GLEW CONFIG QUIET)
if(GLEW_FOUND)
find_package_handle_standard_args(GLEW DEFAULT_MSG GLEW_CONFIG)
+ get_target_property(GLEW_INCLUDE_DIRS GLEW::GLEW INTERFACE_INCLUDE_DIRECTORIES)
+ set(GLEW_INCLUDE_DIR ${GLEW_INCLUDE_DIRS})
+ get_target_property(_GLEW_DEFS GLEW::GLEW INTERFACE_COMPILE_DEFINITIONS)
+ if("${_GLEW_DEFS}" MATCHES "GLEW_STATIC")
+ get_target_property(GLEW_LIBRARY_DEBUG GLEW::GLEW IMPORTED_LOCATION_DEBUG)
+ get_target_property(GLEW_LIBRARY_RELEASE GLEW::GLEW IMPORTED_LOCATION_RELEASE)
+ else()
+ get_target_property(GLEW_LIBRARY_DEBUG GLEW::GLEW IMPORTED_IMPLIB_DEBUG)
+ get_target_property(GLEW_LIBRARY_RELEASE GLEW::GLEW IMPORTED_IMPLIB_RELEASE)
+ endif()
+ get_target_property(_GLEW_LINK_INTERFACE GLEW::GLEW IMPORTED_LINK_INTERFACE_LIBRARIES_RELEASE) # same for debug and release
+ list(APPEND GLEW_LIBRARIES ${_GLEW_LINK_INTERFACE})
+ list(APPEND GLEW_LIBRARY ${_GLEW_LINK_INTERFACE})
+ select_library_configurations(GLEW)
+ if("${_GLEW_DEFS}" MATCHES "GLEW_STATIC")
+ set(GLEW_STATIC_LIBRARIES ${GLEW_LIBRARIES})
+ else()
+ set(GLEW_SHARED_LIBRARIES ${GLEW_LIBRARIES})
+ endif()
+ unset(_GLEW_DEFS)
+ unset(_GLEW_LINK_INTERFACE)
+ unset(GLEW_LIBRARY)
+ unset(GLEW_LIBRARY_DEBUG)
+ unset(GLEW_LIBRARY_RELEASE)
return()
endif()
@@ -171,8 +196,6 @@ find_library(GLEW_STATIC_LIBRARY_DEBUG
set(CMAKE_FIND_LIBRARY_SUFFIXES ${__GLEW_CURRENT_FIND_LIBRARY_SUFFIXES})
unset(__GLEW_CURRENT_FIND_LIBRARY_SUFFIXES)
-include(${CMAKE_CURRENT_LIST_DIR}/SelectLibraryConfigurations.cmake)
-
select_library_configurations(GLEW_SHARED)
select_library_configurations(GLEW_STATIC)
diff --git a/Modules/FindGTK2.cmake b/Modules/FindGTK2.cmake
index 00bfc29..4634876 100644
--- a/Modules/FindGTK2.cmake
+++ b/Modules/FindGTK2.cmake
@@ -313,6 +313,7 @@ function(_GTK2_FIND_INCLUDE_DIR _var _hdr)
/usr/openwin/lib
/sw/lib
/opt/local/lib
+ /opt/homebrew/lib
/usr/pkg/lib
/usr/pkg/include/glib
$ENV{GTKMM_BASEPATH}/include
diff --git a/Modules/FindICU.cmake b/Modules/FindICU.cmake
index 91dcba5..b4f4d71 100644
--- a/Modules/FindICU.cmake
+++ b/Modules/FindICU.cmake
@@ -254,13 +254,6 @@ function(_ICU_FIND)
set("${component_found}" ON)
set("${component_found_compat}" ON)
list(APPEND ICU_LIBRARY "${${component_cache}}")
- endif()
- mark_as_advanced("${component_found}")
- mark_as_advanced("${component_found_compat}")
- set("${component_cache}" "${${component_cache}}" PARENT_SCOPE)
- set("${component_found}" "${${component_found}}" PARENT_SCOPE)
- set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE)
- if(component_found OR component_found_compat)
if (ICU_FIND_REQUIRED_${component})
list(APPEND ICU_LIBS_FOUND "${component} (required): ${${component_cache}}")
else()
@@ -274,6 +267,11 @@ function(_ICU_FIND)
list(APPEND ICU_LIBS_NOTFOUND "${component} (optional)")
endif()
endif()
+ mark_as_advanced("${component_found}")
+ mark_as_advanced("${component_found_compat}")
+ set("${component_cache}" "${${component_cache}}" PARENT_SCOPE)
+ set("${component_found}" "${${component_found}}" PARENT_SCOPE)
+ set("${component_found_compat}" "${${component_found_compat}}" PARENT_SCOPE)
endforeach()
set(_ICU_REQUIRED_LIBS_FOUND "${ICU_REQUIRED_LIBS_FOUND}" PARENT_SCOPE)
set(ICU_LIBRARY "${ICU_LIBRARY}" PARENT_SCOPE)
diff --git a/Modules/FindLAPACK.cmake b/Modules/FindLAPACK.cmake
index b08b359..4151116 100644
--- a/Modules/FindLAPACK.cmake
+++ b/Modules/FindLAPACK.cmake
@@ -35,6 +35,13 @@ The following variables may be set to influence this module's behavior:
if set ``pkg-config`` will be used to search for a LAPACK library first
and if one is found that is preferred
+``BLA_PKGCONFIG_LAPACK``
+ .. versionadded:: 3.25
+
+ If set, the ``pkg-config`` method will look for this module name instead of
+ just ``lapack``.
+
+
``BLA_SIZEOF_INTEGER``
.. versionadded:: 3.22
@@ -278,8 +285,11 @@ endif()
# Search with pkg-config if specified
if(BLA_PREFER_PKGCONFIG)
+ if(NOT BLA_PKGCONFIG_LAPACK)
+ set(BLA_PKGCONFIG_LAPACK "lapack")
+ endif()
find_package(PkgConfig QUIET)
- pkg_check_modules(PKGC_LAPACK QUIET lapack)
+ pkg_check_modules(PKGC_LAPACK QUIET ${BLA_PKGCONFIG_LAPACK})
if(PKGC_LAPACK_FOUND)
set(LAPACK_FOUND TRUE)
set(LAPACK_LIBRARIES "${PKGC_LAPACK_LINK_LIBRARIES}")
diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake
index 48ef5eb..ec2c345 100644
--- a/Modules/FindMatlab.cmake
+++ b/Modules/FindMatlab.cmake
@@ -85,10 +85,18 @@ Module Input Variables
Users or projects may set the following variables to configure the module
behavior:
+:variable:`Matlab_ROOT <<PackageName>_ROOT>`
+ .. versionadded:: 3.25
+
+ Default value for :variable:`Matlab_ROOT_DIR`, the root of the Matlab
+ installation.
+
:variable:`Matlab_ROOT_DIR`
- the root of the Matlab installation.
+ The root of the Matlab installation.
+
:variable:`MATLAB_FIND_DEBUG`
outputs debug information
+
:variable:`MATLAB_ADDITIONAL_VERSIONS`
additional versions of Matlab for the automatic retrieval of the installed
versions.
@@ -843,6 +851,15 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve
endif()
endif()
+ if(NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp")
+ # last resort check as some HPC with "module load matlab" not enacted fail to catch in earlier checks
+ # and error CMake configure even if find_package(Matlab) is not REQUIRED
+ if(MATLAB_FIND_DEBUG)
+ message(WARNING "[MATLAB] Unable to determine the version of Matlab. The version log file does not exist.")
+ endif()
+ return()
+ endif()
+
# if successful, read back the log
file(READ "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp" _matlab_version_from_cmd)
file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp")
@@ -1572,6 +1589,13 @@ endfunction()
# this variable will get all Matlab installations found in the current system.
set(_matlab_possible_roots)
+if(NOT DEFINED Matlab_ROOT AND DEFINED ENV{Matlab_ROOT})
+ set(Matlab_ROOT $ENV{Matlab_ROOT})
+endif()
+if(DEFINED Matlab_ROOT)
+ set(Matlab_ROOT_DIR ${Matlab_ROOT})
+endif()
+
if(Matlab_ROOT_DIR)
# if the user specifies a possible root, we keep this one
diff --git a/Modules/FindOpenACC.cmake b/Modules/FindOpenACC.cmake
index cf58f3b..71bd84f 100644
--- a/Modules/FindOpenACC.cmake
+++ b/Modules/FindOpenACC.cmake
@@ -27,6 +27,13 @@ The module provides :prop_tgt:`IMPORTED` targets:
Variables
^^^^^^^^^
+The module defines the following variables:
+
+``OpenACC_FOUND``
+ .. versionadded:: 3.25
+
+ Variable indicating that OpenACC flags for at least one languages have been found.
+
This module will set the following variables per language in your
project, where ``<lang>`` is one of C, CXX, or Fortran:
@@ -270,6 +277,9 @@ foreach (LANG IN ITEMS C CXX Fortran)
REQUIRED_VARS OpenACC_${LANG}_FLAGS
VERSION_VAR OpenACC_${LANG}_VERSION
)
+ if(OpenACC_${LANG}_FOUND)
+ set(OpenACC_FOUND TRUE)
+ endif()
endif()
endforeach()
diff --git a/Modules/FindOpenAL.cmake b/Modules/FindOpenAL.cmake
index b5b92c5..53aafdc 100644
--- a/Modules/FindOpenAL.cmake
+++ b/Modules/FindOpenAL.cmake
@@ -29,6 +29,16 @@ OpenAL is searched in the following order:
5. Manually compiled framework: ``/Library/Frameworks``.
6. Add-on package: ``/opt``.
+IMPORTED Targets
+^^^^^^^^^^^^^^^^
+
+.. versionadded:: 3.25
+
+This module defines the :prop_tgt:`IMPORTED` target:
+
+``OpenAL::OpenAL``
+ The OpenAL library, if found.
+
Result Variables
^^^^^^^^^^^^^^^^
@@ -94,3 +104,19 @@ find_package_handle_standard_args(
)
mark_as_advanced(OPENAL_LIBRARY OPENAL_INCLUDE_DIR)
+
+if(OPENAL_INCLUDE_DIR AND OPENAL_LIBRARY)
+ if(NOT TARGET OpenAL::OpenAL)
+ if(EXISTS "${OPENAL_LIBRARY}")
+ add_library(OpenAL::OpenAL UNKNOWN IMPORTED)
+ set_target_properties(OpenAL::OpenAL PROPERTIES
+ IMPORTED_LOCATION "${OPENAL_LIBRARY}")
+ else()
+ add_library(OpenAL::OpenAL INTERFACE IMPORTED)
+ set_target_properties(OpenAL::OpenAL PROPERTIES
+ IMPORTED_LIBNAME "${OPENAL_LIBRARY}")
+ endif()
+ set_target_properties(OpenAL::OpenAL PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${OPENAL_INCLUDE_DIR}")
+ endif()
+endif()
diff --git a/Modules/FindOpenGL.cmake b/Modules/FindOpenGL.cmake
index d6d1c00..a9a1b2a 100644
--- a/Modules/FindOpenGL.cmake
+++ b/Modules/FindOpenGL.cmake
@@ -377,7 +377,7 @@ else()
(NOT OPENGL_USE_EGL AND
NOT OPENGL_glx_LIBRARY AND
OPENGL_gl_LIBRARY))
- list(APPEND _OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY)
+ list(PREPEND _OpenGL_REQUIRED_VARS OPENGL_gl_LIBRARY)
endif()
# We always need the 'gl.h' include dir.
diff --git a/Modules/FindOpenMP.cmake b/Modules/FindOpenMP.cmake
index ecfb7f9..8a061e2 100644
--- a/Modules/FindOpenMP.cmake
+++ b/Modules/FindOpenMP.cmake
@@ -238,11 +238,29 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
OpenMP_${LANG}_IMPLICIT_FWK_DIRS
OpenMP_${LANG}_LOG_VAR
"${CMAKE_${LANG}_IMPLICIT_OBJECT_REGEX}"
+ LANGUAGE ${LANG}
)
file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Parsed ${LANG} OpenMP implicit link information from above output:\n${OpenMP_${LANG}_LOG_VAR}\n\n")
+ # For LCC we should additionally alanyze -print-search-dirs output
+ # to check for additional implicit_dirs.
+ # Note: This won't work if CMP0129 policy is set to OLD!
+ if("${CMAKE_${LANG}_COMPILER_ID}" STREQUAL "LCC")
+ execute_process(
+ COMMAND ${CMAKE_${LANG}_COMPILER} -print-search-dirs
+ OUTPUT_VARIABLE output_lines
+ COMMAND_ERROR_IS_FATAL ANY
+ ERROR_QUIET)
+ if("${output_lines}" MATCHES ".*\nlibraries:[ \t]+(.*:)\n.*")
+ string(REPLACE ":" ";" implicit_dirs_addon "${CMAKE_MATCH_1}")
+ list(PREPEND OpenMP_${LANG}_IMPLICIT_LINK_DIRS ${implicit_dirs_addon})
+ file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ " Extended OpenMP library search paths: [${implicit_dirs}]\n")
+ endif()
+ endif()
+
unset(_OPENMP_LIB_NAMES)
foreach(_OPENMP_IMPLICIT_LIB IN LISTS OpenMP_${LANG}_IMPLICIT_LIBRARIES)
get_filename_component(_OPENMP_IMPLICIT_LIB_DIR "${_OPENMP_IMPLICIT_LIB}" DIRECTORY)
@@ -262,7 +280,9 @@ function(_OPENMP_GET_FLAGS LANG FLAG_MODE OPENMP_FLAG_VAR OPENMP_LIB_NAMES_VAR)
DOC "Path to the ${_OPENMP_IMPLICIT_LIB_PLAIN} library for OpenMP"
HINTS ${OpenMP_${LANG}_IMPLICIT_LINK_DIRS}
CMAKE_FIND_ROOT_PATH_BOTH
- NO_DEFAULT_PATH
+ NO_PACKAGE_ROOT_PATH
+ NO_CMAKE_PATH
+ NO_CMAKE_ENVIRONMENT_PATH
)
endif()
mark_as_advanced(OpenMP_${_OPENMP_IMPLICIT_LIB_PLAIN}_LIBRARY)
@@ -460,10 +480,14 @@ foreach(LANG IN ITEMS C CXX)
if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND"
OR NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
_OPENMP_GET_FLAGS("${LANG}" "${LANG}" OpenMP_${LANG}_FLAGS_WORK OpenMP_${LANG}_LIB_NAMES_WORK)
- set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
- CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE)
- set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
- CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE)
+ if(NOT DEFINED OpenMP_${LANG}_FLAGS OR "${OpenMP_${LANG}_FLAGS}" STREQUAL "NOTFOUND")
+ set(OpenMP_${LANG}_FLAGS "${OpenMP_${LANG}_FLAGS_WORK}"
+ CACHE STRING "${LANG} compiler flags for OpenMP parallelization" FORCE)
+ endif()
+ if(NOT DEFINED OpenMP_${LANG}_LIB_NAMES OR "${OpenMP_${LANG}_LIB_NAMES}" STREQUAL "NOTFOUND")
+ set(OpenMP_${LANG}_LIB_NAMES "${OpenMP_${LANG}_LIB_NAMES_WORK}"
+ CACHE STRING "${LANG} compiler libraries for OpenMP parallelization" FORCE)
+ endif()
mark_as_advanced(OpenMP_${LANG}_FLAGS OpenMP_${LANG}_LIB_NAMES)
endif()
endif()
@@ -479,10 +503,14 @@ if(CMAKE_Fortran_COMPILER_LOADED)
set(OpenMP_Fortran_HAVE_OMPLIB_MODULE TRUE CACHE BOOL INTERNAL "")
endif()
- set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
- CACHE STRING "Fortran compiler flags for OpenMP parallelization")
- set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
- CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
+ if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND")
+ set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
+ CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE)
+ endif()
+ if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND")
+ set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
+ CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE)
+ endif()
mark_as_advanced(OpenMP_Fortran_FLAGS OpenMP_Fortran_LIB_NAMES)
endif()
@@ -495,11 +523,14 @@ if(CMAKE_Fortran_COMPILER_LOADED)
set(OpenMP_Fortran_HAVE_OMPLIB_HEADER TRUE CACHE BOOL INTERNAL "")
endif()
- set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
- CACHE STRING "Fortran compiler flags for OpenMP parallelization")
-
- set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES}"
- CACHE STRING "Fortran compiler libraries for OpenMP parallelization")
+ if(NOT DEFINED OpenMP_Fortran_FLAGS OR "${OpenMP_Fortran_FLAGS}" STREQUAL "NOTFOUND")
+ set(OpenMP_Fortran_FLAGS "${OpenMP_Fortran_FLAGS_WORK}"
+ CACHE STRING "Fortran compiler flags for OpenMP parallelization" FORCE)
+ endif()
+ if(NOT DEFINED OpenMP_Fortran_LIB_NAMES OR "${OpenMP_Fortran_LIB_NAMES}" STREQUAL "NOTFOUND")
+ set(OpenMP_Fortran_LIB_NAMES "${OpenMP_Fortran_LIB_NAMES_WORK}"
+ CACHE STRING "Fortran compiler libraries for OpenMP parallelization" FORCE)
+ endif()
endif()
if(OpenMP_Fortran_HAVE_OMPLIB_MODULE)
@@ -571,7 +602,8 @@ foreach(LANG IN LISTS OpenMP_FINDLIST)
separate_arguments(_OpenMP_${LANG}_OPTIONS NATIVE_COMMAND "${OpenMP_${LANG}_FLAGS}")
set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
INTERFACE_COMPILE_OPTIONS "$<$<COMPILE_LANGUAGE:${LANG}>:${_OpenMP_${LANG}_OPTIONS}>")
- if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu")
+ if(CMAKE_${LANG}_COMPILER_ID STREQUAL "Fujitsu"
+ OR ${CMAKE_${LANG}_COMPILER_ID} STREQUAL "IntelLLVM")
set_property(TARGET OpenMP::OpenMP_${LANG} PROPERTY
INTERFACE_LINK_OPTIONS "${OpenMP_${LANG}_FLAGS}")
endif()
diff --git a/Modules/FindOpenSP.cmake b/Modules/FindOpenSP.cmake
new file mode 100644
index 0000000..c903ad7
--- /dev/null
+++ b/Modules/FindOpenSP.cmake
@@ -0,0 +1,155 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindOpenSP
+----------
+
+Try to find the OpenSP library.
+
+.. versionadded:: 3.25
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``OpenSP_FOUND``
+ True if (the requested version of) ``OpenSP`` is available
+
+``OpenSP_VERSION``
+ The version of ``OpenSP``
+
+``OpenSP_VERSION_MAJOR``
+ The major version of ``OpenSP``
+
+``OpenSP_VERSION_MINOR``
+ The minor version of ``OpenSP``
+
+``OpenSP_VERSION_PATCH``
+ The patch version of ``OpenSP``
+
+``OpenSP_INCLUDE_DIRS``
+ The include dirs of ``OpenSP`` with its headers
+
+``OpenSP_LIBRARIES``
+ The OpenSP library for use with target_link_libraries().
+ This can be passed to target_link_libraries() instead of
+ the :prop_tgt:`IMPORTED` ``OpenSP::OpenSP`` target
+
+``OpenSP_MULTI_BYTE``
+ True if ``SP_MULTI_BYTE`` was found to be defined in OpenSP's ``config.h``
+ header file, which indicates that the ``OpenSP`` library was compiled with
+ support for multi-byte characters. The consuming target needs to define the
+ ``SP_MULTI_BYTE`` to match this value in order to avoid issues with character
+ decoding.
+
+IMPORTED Targets
+^^^^^^^^^^^^^^^^
+
+This module defines the :prop_tgt:`IMPORTED` target ``OpenSP::OpenSP``, if
+OpenSP has been found.
+
+Cache variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``OpenSP_INCLUDE_DIR``
+ the OpenSP include directory
+
+``OpenSP_LIBRARY``
+ the absolute path of the osp library
+
+#]=======================================================================]
+
+if (NOT OpenSP_INCLUDE_DIR AND NOT OpenSP_LIBRARY)
+ find_package(PkgConfig)
+ if (PkgConfig_FOUND)
+ pkg_check_modules(OpenSP IMPORTED_TARGET GLOBAL opensp)
+
+ if (OpenSP_FOUND)
+ add_library(OpenSP::OpenSP INTERFACE IMPORTED)
+ target_link_libraries(OpenSP::OpenSP INTERFACE PkgConfig::OpenSP)
+
+ set(OpenSP_INCLUDE_DIR ${OpenSP_INCLUDE_DIRS})
+ set(OpenSP_LIBRARY ${OpenSP_LIBRARIES})
+ endif ()
+ endif ()
+endif ()
+
+if (NOT OpenSP_INCLUDE_DIR)
+ find_path(OpenSP_INCLUDE_DIR
+ NAMES ParserEventGeneratorKit.h
+ PATH_SUFFIXES OpenSP opensp
+ DOC "The OpenSP include directory"
+ )
+endif ()
+
+if (NOT OpenSP_LIBRARY)
+ find_library(OpenSP_LIBRARY_RELEASE
+ NAMES osp libosp opensp libopensp sp133 libsp
+ )
+
+ find_library(OpenSP_LIBRARY_DEBUG
+ NAMES ospd libospd openspd libopenspd sp133d libspd
+ )
+
+ include(SelectLibraryConfigurations)
+ select_library_configurations(OpenSP)
+endif ()
+
+if (OpenSP_INCLUDE_DIR AND OpenSP_LIBRARY)
+ if (EXISTS "${OpenSP_INCLUDE_DIR}/config.h")
+ if (NOT OpenSP_VERSION)
+ file(STRINGS "${OpenSP_INCLUDE_DIR}/config.h" opensp_version_str REGEX "^#define[\t ]+SP_VERSION[\t ]+\".*\"")
+ string(REGEX REPLACE "^.*SP_VERSION[\t ]+\"([^\"]*)\".*$" "\\1" OpenSP_VERSION "${opensp_version_str}")
+ unset(opensp_version_str)
+ endif ()
+
+ if (OpenSP_VERSION MATCHES [=[([0-9]+)\.([0-9]+)\.([0-9]+)]=])
+ set(OpenSP_VERSION_MAJOR "${CMAKE_MATCH_1}")
+ set(OpenSP_VERSION_MINOR "${CMAKE_MATCH_2}")
+ set(OpenSP_VERSION_PATCH "${CMAKE_MATCH_3}")
+ endif ()
+
+ include(CheckCXXSymbolExists)
+ check_cxx_symbol_exists(SP_MULTI_BYTE "${OpenSP_INCLUDE_DIR}/config.h" OpenSP_MULTI_BYTE)
+ endif ()
+
+ if (NOT TARGET OpenSP::OpenSP)
+ set(OpenSP_INCLUDE_DIRS ${OpenSP_INCLUDE_DIR})
+
+ add_library(OpenSP::OpenSP UNKNOWN IMPORTED)
+ set_target_properties(OpenSP::OpenSP PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${OpenSP_INCLUDE_DIRS}")
+
+ if (OpenSP_LIBRARY_RELEASE)
+ set_target_properties(OpenSP::OpenSP PROPERTIES IMPORTED_LOCATION_RELEASE "${OpenSP_LIBRARY_RELEASE}")
+ set_property(TARGET OpenSP::OpenSP APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE)
+ endif ()
+
+ if (OpenSP_LIBRARY_DEBUG)
+ set_target_properties(OpenSP::OpenSP PROPERTIES IMPORTED_LOCATION_DEBUG "${OpenSP_LIBRARY_DEBUG}")
+ set_property(TARGET OpenSP::OpenSP APPEND PROPERTY IMPORTED_CONFIGURATIONS DEBUG)
+ endif ()
+
+ if (NOT OpenSP_LIBRARY_RELEASE AND NOT OpenSP_LIBRARY_DEBUG)
+ set_property(TARGET OpenSP::OpenSP APPEND PROPERTY IMPORTED_LOCATION "${OpenSP_LIBRARY}")
+ endif ()
+ endif ()
+endif ()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(OpenSP
+ FOUND_VAR OpenSP_FOUND
+ REQUIRED_VARS OpenSP_LIBRARY OpenSP_INCLUDE_DIR
+ VERSION_VAR OpenSP_VERSION
+ )
+
+mark_as_advanced(OpenSP_INCLUDE_DIR OpenSP_LIBRARY OpenSP_MULTI_BYTE)
+
+include(FeatureSummary)
+set_package_properties(OpenSP PROPERTIES
+ URL "http://openjade.sourceforge.net/doc/index.htm"
+ DESCRIPTION "An SGML System Conforming to International Standard ISO 8879"
+ )
diff --git a/Modules/FindOpenSSL.cmake b/Modules/FindOpenSSL.cmake
index 9278566..352c4cc 100644
--- a/Modules/FindOpenSSL.cmake
+++ b/Modules/FindOpenSSL.cmake
@@ -90,13 +90,25 @@ This module will set the following variables in your project:
Hints
^^^^^
-Set ``OPENSSL_ROOT_DIR`` to the root directory of an OpenSSL installation.
+The following variables may be set to control search behavior:
-.. versionadded:: 3.4
- Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries.
+``OPENSSL_ROOT_DIR``
+ Set to the root directory of an OpenSSL installation.
+
+``OPENSSL_USE_STATIC_LIBS``
+ .. versionadded:: 3.4
+
+ Set to ``TRUE`` to look for static libraries.
+
+``OPENSSL_MSVC_STATIC_RT``
+ .. versionadded:: 3.5
+
+ Set to ``TRUE`` to choose the MT version of the lib.
-.. versionadded:: 3.5
- Set ``OPENSSL_MSVC_STATIC_RT`` set ``TRUE`` to choose the MT version of the lib.
+``ENV{PKG_CONFIG_PATH}``
+ On UNIX-like systems, ``pkg-config`` is used to locate the system OpenSSL.
+ Set the ``PKG_CONFIG_PATH`` environment varialbe to look in alternate
+ locations. Useful on multi-lib systems.
#]=======================================================================]
macro(_OpenSSL_test_and_find_dependencies ssl_library crypto_library)
diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake
index c4fae6b..7a127e4 100644
--- a/Modules/FindPython/Support.cmake
+++ b/Modules/FindPython/Support.cmake
@@ -14,6 +14,8 @@ cmake_policy(PUSH)
cmake_policy (SET CMP0012 NEW)
# IN_LIST operator
cmake_policy (SET CMP0057 NEW)
+# registry view behavior
+cmake_policy (SET CMP0134 NEW)
if (NOT DEFINED _PYTHON_PREFIX)
message (FATAL_ERROR "FindPython: INTERNAL ERROR")
@@ -175,30 +177,31 @@ function (_PYTHON_GET_REGISTRIES _PYTHON_PGR_REGISTRY_PATHS)
foreach (version IN LISTS _PGR_VERSION)
string (REPLACE "." "" version_no_dots ${version})
list (APPEND registries
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath])
+ [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}-${_${_PYTHON_PREFIX}_ARCH}/InstallPath]
+ [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}-${_${_PYTHON_PREFIX}_ARCH2}/InstallPath])
if (version VERSION_GREATER_EQUAL "3.5")
+ # cmake_host_system_information is not usable in bootstrap
get_filename_component (arch "[HKEY_CURRENT_USER\\Software\\Python\\PythonCore\\${version};SysArchitecture]" NAME)
if (arch MATCHES "(${_${_PYTHON_PREFIX}_ARCH}|${_${_PYTHON_PREFIX}_ARCH2})bit")
list (APPEND registries
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath])
+ [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}/InstallPath])
endif()
else()
list (APPEND registries
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath])
+ [HKEY_CURRENT_USER/SOFTWARE/Python/PythonCore/${version}/InstallPath])
endif()
list (APPEND registries
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${version}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath]
- [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}\\InstallPath])
+ [HKEY_CURRENT_USER/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}/InstallPath]
+ [HKEY_CURRENT_USER/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}/InstallPath]
+ [HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${version}-${_${_PYTHON_PREFIX}_ARCH}/InstallPath]
+ [HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${version}-${_${_PYTHON_PREFIX}_ARCH2}/InstallPath]
+ [HKEY_LOCAL_MACHINE/SOFTWARE/Python/PythonCore/${version}/InstallPath]
+ [HKEY_LOCAL_MACHINE/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH}/InstallPath]
+ [HKEY_LOCAL_MACHINE/SOFTWARE/Python/ContinuumAnalytics/Anaconda${version_no_dots}-${_${_PYTHON_PREFIX}_ARCH2}/InstallPath])
endforeach()
elseif (implementation STREQUAL "IronPython")
foreach (version IN LISTS _PGR_VERSION)
- list (APPEND registries [HKEY_LOCAL_MACHINE\\SOFTWARE\\IronPython\\${version}\\InstallPath])
+ list (APPEND registries [HKEY_LOCAL_MACHINE/SOFTWARE/IronPython/${version}/InstallPath])
endforeach()
endif()
endforeach()
@@ -711,7 +714,7 @@ function (_PYTHON_VALIDATE_INTERPRETER)
if (_PVI_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_EXECUTABLE}")
# interpreter does not exist anymore
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot find the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot find the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -732,7 +735,7 @@ function (_PYTHON_VALIDATE_INTERPRETER)
endif()
if (NOT abi IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
# incompatible ABI
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong ABI for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -748,7 +751,7 @@ function (_PYTHON_VALIDATE_INTERPRETER)
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (result)
# interpreter is not usable
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -773,7 +776,7 @@ function (_PYTHON_VALIDATE_INTERPRETER)
if (_PVI_EXACT AND NOT version VERSION_EQUAL _PVI_VERSION)
# interpreter has wrong version
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
else()
@@ -782,7 +785,7 @@ function (_PYTHON_VALIDATE_INTERPRETER)
string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${_PVI_VERSION}")
if (NOT major_version VERSION_EQUAL expected_major_version
OR NOT version VERSION_GREATER_EQUAL _PVI_VERSION)
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -794,7 +797,7 @@ function (_PYTHON_VALIDATE_INTERPRETER)
find_package_check_version ("${version}" in_range HANDLE_VERSION_RANGE)
if (NOT in_range)
# interpreter has invalid version
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
endif()
@@ -813,9 +816,9 @@ function (_PYTHON_VALIDATE_INTERPRETER)
if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
# interpreter not usable or has wrong major version
if (result)
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
else()
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong major version for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
endif()
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
@@ -836,9 +839,9 @@ function (_PYTHON_VALIDATE_INTERPRETER)
if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P)
# interpreter not usable or has wrong architecture
if (result)
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot use the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
else()
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Wrong architecture for the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
endif()
set_property (CACHE _${_PYTHON_PREFIX}_EXECUTABLE PROPERTY VALUE "${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND")
return()
@@ -846,6 +849,14 @@ function (_PYTHON_VALIDATE_INTERPRETER)
endif()
endfunction()
+function(_python_validate_find_interpreter status interpreter)
+ set(_${_PYTHON_PREFIX}_EXECUTABLE "${interpreter}" CACHE FILEPATH "" FORCE)
+ _python_validate_interpreter (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ if (NOT _${_PYTHON_PREFIX}_EXECUTABLE)
+ set (${status} FALSE PARENT_SCOPE)
+ endif()
+endfunction()
+
function (_PYTHON_VALIDATE_COMPILER)
if (NOT _${_PYTHON_PREFIX}_COMPILER)
@@ -856,7 +867,7 @@ function (_PYTHON_VALIDATE_COMPILER)
if (_PVC_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_COMPILER}")
# Compiler does not exist anymore
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot find the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot find the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
return()
endif()
@@ -883,7 +894,7 @@ function (_PYTHON_VALIDATE_COMPILER)
file (REMOVE_RECURSE "${working_dir}")
if (result)
# compiler is not usable
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot use the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot use the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
return()
endif()
@@ -909,7 +920,7 @@ function (_PYTHON_VALIDATE_COMPILER)
if (_PVC_EXACT AND NOT version VERSION_EQUAL _PVC_VERSION)
# interpreter has wrong version
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
return()
else()
@@ -918,7 +929,7 @@ function (_PYTHON_VALIDATE_COMPILER)
string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" expected_major_version "${_PVC_VERSION}")
if (NOT major_version VERSION_EQUAL expected_major_version
OR NOT version VERSION_GREATER_EQUAL _PVC_VERSION)
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
return()
endif()
@@ -930,7 +941,7 @@ function (_PYTHON_VALIDATE_COMPILER)
find_package_check_version ("${version}" in_range HANDLE_VERSION_RANGE)
if (NOT in_range)
# interpreter has invalid version
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
return()
endif()
@@ -939,13 +950,21 @@ function (_PYTHON_VALIDATE_COMPILER)
string(REGEX REPLACE "^([0-9]+)\\.?.*$" "\\1" major_version "${version}")
if (NOT major_version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
# Compiler has wrong major version
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Wrong major version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Wrong major version for the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
set_property (CACHE _${_PYTHON_PREFIX}_COMPILER PROPERTY VALUE "${_PYTHON_PREFIX}_COMPILER-NOTFOUND")
return()
endif()
endif()
endfunction()
+function(_python_validate_find_compiler status compiler)
+ set(_${_PYTHON_PREFIX}_COMPILER "${compiler}" CACHE FILEPATH "" FORCE)
+ _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ if (NOT _${_PYTHON_PREFIX}_COMPILER)
+ set (${status} FALSE PARENT_SCOPE)
+ endif()
+endfunction()
+
function (_PYTHON_VALIDATE_LIBRARY)
if (NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
@@ -957,7 +976,7 @@ function (_PYTHON_VALIDATE_LIBRARY)
if (_PVL_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
# library does not exist anymore
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
if (WIN32)
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_DEBUG PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_DEBUG-NOTFOUND")
@@ -971,7 +990,7 @@ function (_PYTHON_VALIDATE_LIBRARY)
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT lib_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
# incompatible ABI
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
else()
if (_PVL_VERSION OR _PVL_IN_RANGE)
@@ -980,7 +999,7 @@ function (_PYTHON_VALIDATE_LIBRARY)
string (REGEX MATCH "[0-9](\\.[0-9]+)?" version "${_PVL_VERSION}")
if ((_PVL_EXACT AND NOT lib_VERSION VERSION_EQUAL version) OR (lib_VERSION VERSION_LESS version))
# library has wrong version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
endif()
endif()
@@ -990,14 +1009,14 @@ function (_PYTHON_VALIDATE_LIBRARY)
find_package_check_version ("${lib_VERSION}" in_range HANDLE_VERSION_RANGE)
if (NOT in_range)
# library has wrong version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Wrong version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
endif()
endif()
else()
if (NOT lib_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
# library has wrong major version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Wrong major version for the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
endif()
endif()
@@ -1023,7 +1042,7 @@ function (_PYTHON_VALIDATE_INCLUDE_DIR)
if (_PVID_CHECK_EXISTS AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
# include file does not exist anymore
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
return()
endif()
@@ -1033,14 +1052,14 @@ function (_PYTHON_VALIDATE_INCLUDE_DIR)
if (DEFINED _${_PYTHON_PREFIX}_FIND_ABI AND NOT inc_ABI IN_LIST _${_PYTHON_PREFIX}_ABIFLAGS)
# incompatible ABI
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong ABI for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Wrong ABI for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
else()
if (_PVID_VERSION OR _PVID_IN_RANGE)
if (_PVID_VERSION)
if ((_PVID_EXACT AND NOT inc_VERSION VERSION_EQUAL expected_version) OR (inc_VERSION VERSION_LESS expected_version))
# include dir has wrong version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
endif()
endif()
@@ -1050,14 +1069,14 @@ function (_PYTHON_VALIDATE_INCLUDE_DIR)
find_package_check_version ("${inc_VERSION}" in_range HANDLE_VERSION_RANGE)
if (NOT in_range)
# include dir has wrong version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Wrong version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
endif()
endif()
else()
if (NOT inc_VERSION_MAJOR VERSION_EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR)
# include dir has wrong major version
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Wrong major version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"" PARENT_SCOPE)
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Wrong major version for the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
endif()
endif()
@@ -1247,12 +1266,14 @@ if (DEFINED ${_PYTHON_PREFIX}_FIND_STRATEGY)
endif()
# Python and Anaconda distributions: define which architectures can be used
+unset (_${_PYTHON_PREFIX}_REGISTRY_VIEW)
if (CMAKE_SIZEOF_VOID_P)
math (EXPR _${_PYTHON_PREFIX}_ARCH "${CMAKE_SIZEOF_VOID_P} * 8")
if ("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
OR "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
# In this case, search only for 64bit or 32bit
set (_${_PYTHON_PREFIX}_ARCH2 ${_${_PYTHON_PREFIX}_ARCH})
+ set (_${_PYTHON_PREFIX}_REGISTRY_VIEW REGISTRY_VIEW ${_${_PYTHON_PREFIX}_ARCH})
else()
if (_${_PYTHON_PREFIX}_ARCH EQUAL "32")
set (_${_PYTHON_PREFIX}_ARCH2 64)
@@ -1506,9 +1527,13 @@ endfunction()
unset (_${_PYTHON_PREFIX}_REQUIRED_VARS)
unset (_${_PYTHON_PREFIX}_CACHED_VARS)
unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE)
+set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE CACHE INTERNAL "Interpreter reason failure")
unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE)
+set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE CACHE INTERNAL "Compiler reason failure")
unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE)
+set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE CACHE INTERNAL "Development reason failure")
unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
+set (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE CACHE INTERNAL "NumPy reason failure")
# preamble
@@ -1590,9 +1615,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
-
- _python_validate_interpreter (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1612,8 +1636,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1626,9 +1650,10 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ ${_${_PYTHON_PREFIX}_REGISTRY_VIEW}
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1641,8 +1666,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1650,8 +1675,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
NAMES_PER_DIR
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
- _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1663,8 +1688,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_DEFAULT_PATH
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1676,8 +1701,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- _python_validate_interpreter (${${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ ${_${_PYTHON_PREFIX}_REGISTRY_VIEW}
+ NO_DEFAULT_PATH
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1687,9 +1713,9 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endwhile()
else()
# look-up for various versions and locations
- set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS EXACT)
+ set (_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS EXACT)
if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE)
- list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS IN_RANGE)
+ list (APPEND _${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS IN_RANGE)
endif()
foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
@@ -1698,6 +1724,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
_python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
_python_get_registries (_${_PYTHON_PREFIX}_REGISTRY_PATHS VERSION ${_${_PYTHON_PREFIX}_VERSION})
+ set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS})
# Virtual environments handling
if (_${_PYTHON_PREFIX}_FIND_VIRTUALENV MATCHES "^(FIRST|ONLY)$")
@@ -1710,8 +1737,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1731,7 +1758,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_interpreter)
endif()
# Windows registry
@@ -1742,11 +1770,12 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ ${_${_PYTHON_PREFIX}_REGISTRY_VIEW}
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_interpreter)
endif()
- _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1758,21 +1787,18 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
HINTS ${_${_PYTHON_PREFIX}_HINTS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
+
# try using standard paths.
- # NAMES_PER_DIR is not defined on purpose to have a chance to find
- # expected version.
- # For example, typical systems have 'python' for version 2.* and 'python3'
- # for version 3.*. So looking for names per dir will find, potentially,
- # systematically 'python' (i.e. version 2) even if version 3 is searched.
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
NAMES ${_${_PYTHON_PREFIX}_NAMES}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
- _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NAMES_PER_DIR
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ VALIDATOR _python_validate_find_interpreter)
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1784,7 +1810,8 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
+ NO_DEFAULT_PATH
+ VALIDATOR _python_validate_find_interpreter)
endif()
# Windows registry
@@ -1794,10 +1821,11 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
+ ${_${_PYTHON_PREFIX}_REGISTRY_VIEW}
+ NO_DEFAULT_PATH
+ VALIDATOR _python_validate_find_interpreter)
endif()
- _python_validate_interpreter (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
if (_${_PYTHON_PREFIX}_EXECUTABLE)
break()
endif()
@@ -1806,15 +1834,12 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
if (NOT _${_PYTHON_PREFIX}_EXECUTABLE AND
NOT _${_PYTHON_PREFIX}_FIND_VIRTUALENV STREQUAL "ONLY")
# No specific version found. Retry with generic names and standard paths.
- # NAMES_PER_DIR is not defined on purpose to have a chance to find
- # expected version.
- # For example, typical systems have 'python' for version 2.* and 'python3'
- # for version 3.*. So looking for names per dir will find, potentially,
- # systematically 'python' (i.e. version 2) even if version 3 is searched.
_python_get_names (_${_PYTHON_PREFIX}_NAMES POSIX INTERPRETER)
+ unset (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS)
find_program (_${_PYTHON_PREFIX}_EXECUTABLE
- NAMES ${_${_PYTHON_PREFIX}_NAMES})
- _python_validate_interpreter ()
+ NAMES ${_${_PYTHON_PREFIX}_NAMES}
+ NAMES_PER_DIR
+ VALIDATOR _python_validate_find_interpreter)
endif()
endif()
endif()
@@ -1836,7 +1861,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
# Interpreter is not usable
set (_${_PYTHON_PREFIX}_EXECUTABLE_USABLE FALSE)
unset (${_PYTHON_PREFIX}_VERSION)
- set (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE "Cannot run the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
+ set_property (CACHE _${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE PROPERTY VALUE "Cannot run the interpreter \"${_${_PYTHON_PREFIX}_EXECUTABLE}\"")
endif()
endif()
@@ -1884,7 +1909,7 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endif()
if (${_PYTHON_PREFIX}_Interpreter_FOUND)
- unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE)
+ unset (_${_PYTHON_PREFIX}_Interpreter_REASON_FAILURE CACHE)
# compute and save interpreter signature
string (MD5 __${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_EXECUTABLE}")
@@ -2058,8 +2083,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2072,9 +2097,10 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ ${_${_PYTHON_PREFIX}_REGISTRY_VIEW}
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2087,8 +2113,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2097,8 +2123,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
find_program (_${_PYTHON_PREFIX}_COMPILER
NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
NAMES_PER_DIR
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2110,12 +2136,13 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_DEFAULT_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
endif()
+
# Windows registry
if (CMAKE_HOST_WIN32 AND _${_PYTHON_PREFIX}_FIND_REGISTRY STREQUAL "LAST")
find_program (_${_PYTHON_PREFIX}_COMPILER
@@ -2123,8 +2150,9 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- _python_validate_compiler (${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ ${_${_PYTHON_PREFIX}_REGISTRY_VIEW}
+ NO_DEFAULT_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2134,9 +2162,9 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endwhile()
else()
# try using root dir and registry
- set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS EXACT)
+ set (_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS EXACT)
if (${_PYTHON_PREFIX}_FIND_VERSION_RANGE)
- list (APPEND _${_PYTHON_PREFIX}_VALIDATE_OPTIONS IN_RANGE)
+ list (APPEND _${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS IN_RANGE)
endif()
foreach (_${_PYTHON_PREFIX}_VERSION IN LISTS _${_PYTHON_PREFIX}_FIND_VERSIONS)
@@ -2157,6 +2185,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
IMPLEMENTATIONS IronPython
VERSION ${_${_PYTHON_PREFIX}_VERSION})
+ set (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_COMMON_VALIDATE_OPTIONS})
+
# Apple frameworks handling
if (CMAKE_HOST_APPLE AND _${_PYTHON_PREFIX}_FIND_FRAMEWORK STREQUAL "FIRST")
find_program (_${_PYTHON_PREFIX}_COMPILER
@@ -2168,8 +2198,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NO_CMAKE_PATH
NO_CMAKE_ENVIRONMENT_PATH
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2182,9 +2212,10 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ ${_${_PYTHON_PREFIX}_REGISTRY_VIEW}
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2197,8 +2228,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
NO_SYSTEM_ENVIRONMENT_PATH
- NO_CMAKE_SYSTEM_PATH)
- _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_CMAKE_SYSTEM_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2210,8 +2241,8 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_FRAMEWORK_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ NO_DEFAULT_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2223,8 +2254,9 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
NAMES_PER_DIR
PATHS ${_${_PYTHON_PREFIX}_REGISTRY_PATHS}
PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
- NO_DEFAULT_PATH)
- _python_validate_compiler (VERSION ${_${_PYTHON_PREFIX}_VERSION} ${_${_PYTHON_PREFIX}_VALIDATE_OPTIONS})
+ ${_${_PYTHON_PREFIX}_REGISTRY_VIEW}
+ NO_DEFAULT_PATH
+ VALIDATOR _python_validate_find_compiler)
if (_${_PYTHON_PREFIX}_COMPILER)
break()
endif()
@@ -2240,11 +2272,13 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
IMPLEMENTATIONS IronPython
VERSION ${_${_PYTHON_PREFIX}_FIND_VERSIONS}
COMPILER)
+ unset (_${_PYTHON_PREFIX}_VALIDATE_OPTIONS)
find_program (_${_PYTHON_PREFIX}_COMPILER
NAMES ${_${_PYTHON_PREFIX}_COMPILER_NAMES}
+ NAMES_PER_DIR
HINTS ${_${_PYTHON_PREFIX}_IRON_ROOT} ${_${_PYTHON_PREFIX}_HINTS}
- PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES})
- _python_validate_compiler ()
+ PATH_SUFFIXES ${_${_PYTHON_PREFIX}_PATH_SUFFIXES}
+ VALIDATOR _python_validate_find_compiler)
endif()
endif()
@@ -2285,7 +2319,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
else()
# compiler not usable
set (_${_PYTHON_PREFIX}_COMPILER_USABLE FALSE)
- set (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE "Cannot run the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
+ set_property (CACHE _${_PYTHON_PREFIX}_Compiler_REASON_FAILURE PROPERTY VALUE "Cannot run the compiler \"${_${_PYTHON_PREFIX}_COMPILER}\"")
endif()
file (REMOVE_RECURSE "${_${_PYTHON_PREFIX}_VERSION_DIR}")
endif()
@@ -2304,7 +2338,7 @@ if ("Compiler" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS)
endif()
if (${_PYTHON_PREFIX}_Compiler_FOUND)
- unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE)
+ unset (_${_PYTHON_PREFIX}_Compiler_REASON_FAILURE CACHE)
# compute and save compiler signature
string (MD5 __${_PYTHON_PREFIX}_COMPILER_SIGNATURE "${_${_PYTHON_PREFIX}_SIGNATURE}:${_${_PYTHON_PREFIX}_COMPILER}")
@@ -2786,7 +2820,7 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
set (${_PYTHON_PREFIX}_LIBRARY_RELEASE "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
if (_${_PYTHON_PREFIX}_LIBRARY_RELEASE AND NOT EXISTS "${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}")
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Cannot find the library \"${_${_PYTHON_PREFIX}_LIBRARY_RELEASE}\"")
set_property (CACHE _${_PYTHON_PREFIX}_LIBRARY_RELEASE PROPERTY VALUE "${_PYTHON_PREFIX}_LIBRARY_RELEASE-NOTFOUND")
endif()
@@ -2837,7 +2871,15 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
if ("INCLUDE_DIR" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS)
while (NOT _${_PYTHON_PREFIX}_INCLUDE_DIR)
- if ("LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_ARTIFACTS
+ set (_${_PYTHON_PREFIX}_LIBRARY_REQUIRED TRUE)
+ foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Module Embed)
+ string (TOUPPER "${_${_PYTHON_PREFIX}_COMPONENT}" _${_PYTHON_PREFIX}_ID)
+ if ("Development.${_${_PYTHON_PREFIX}_COMPONENT}" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
+ AND NOT "LIBRARY" IN_LIST _${_PYTHON_PREFIX}_FIND_DEVELOPMENT_${_${_PYTHON_PREFIX}_ID}_ARTIFACTS)
+ set (_${_PYTHON_PREFIX}_LIBRARY_REQUIRED FALSE)
+ endif()
+ endforeach()
+ if (_${_PYTHON_PREFIX}_LIBRARY_REQUIRED
AND NOT _${_PYTHON_PREFIX}_LIBRARY_RELEASE)
# Don't search for include dir if no library was founded
break()
@@ -2939,7 +2981,7 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
set (${_PYTHON_PREFIX}_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
if (_${_PYTHON_PREFIX}_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_INCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_Development_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
+ set_property (CACHE _${_PYTHON_PREFIX}_Development_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_INCLUDE_DIR-NOTFOUND")
endif()
@@ -3033,7 +3075,7 @@ if (("Development.Module" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
AND ${_PYTHON_PREFIX}_Development.Embed_FOUND)
OR (NOT "Development.Embed" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
AND ${_PYTHON_PREFIX}_Development.Module_FOUND))
- unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE)
+ unset (_${_PYTHON_PREFIX}_Development_REASON_FAILURE CACHE)
endif()
if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS
@@ -3144,7 +3186,7 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte
set (${_PYTHON_PREFIX}_NumPy_INCLUDE_DIRS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
if(_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR AND NOT EXISTS "${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}")
- set (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE "Cannot find the directory \"${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}\"")
+ set_property (CACHE _${_PYTHON_PREFIX}_NumPy_REASON_FAILURE PROPERTY VALUE "Cannot find the directory \"${_${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR}\"")
set_property (CACHE _${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR PROPERTY VALUE "${_PYTHON_PREFIX}_NumPy_INCLUDE_DIR-NOTFOUND")
endif()
@@ -3166,7 +3208,7 @@ if ("NumPy" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS AND ${_PYTHON_PREFIX}_Inte
endif()
if (${_PYTHON_PREFIX}_NumPy_FOUND)
- unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE)
+ unset (_${_PYTHON_PREFIX}_NumPy_REASON_FAILURE CACHE)
# compute and save numpy signature
string (MD5 __${_PYTHON_PREFIX}_NUMPY_SIGNATURE "${_${_PYTHON_PREFIX}_INTERPRETER_SIGNATURE}:${_${_PYTHON_PREFIX}_DEVELOPMENT_MODULE_SIGNATURE}:${${_PYTHON_PREFIX}_NumPyINCLUDE_DIR}")
@@ -3196,7 +3238,7 @@ unset (_${_PYTHON_PREFIX}_REASON_FAILURE)
foreach (_${_PYTHON_PREFIX}_COMPONENT IN ITEMS Interpreter Compiler Development NumPy)
if (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE)
string (APPEND _${_PYTHON_PREFIX}_REASON_FAILURE "\n ${_${_PYTHON_PREFIX}_COMPONENT}: ${_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE}")
- unset (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE)
+ unset (_${_PYTHON_PREFIX}_${_${_PYTHON_PREFIX}_COMPONENT}_REASON_FAILURE CACHE)
endif()
endforeach()
diff --git a/Modules/FindRuby.cmake b/Modules/FindRuby.cmake
index a80758d..b14349f 100644
--- a/Modules/FindRuby.cmake
+++ b/Modules/FindRuby.cmake
@@ -369,56 +369,17 @@ if(Ruby_EXECUTABLE AND NOT Ruby_VERSION_MAJOR)
set(Ruby_VERSION_MAJOR 1)
set(Ruby_VERSION_MINOR 9)
endif()
- # check whether we found 2.0.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?0")
+ # check whether we found 2.[0-7].x
+ if(${Ruby_EXECUTABLE} MATCHES "ruby2")
set(Ruby_VERSION_MAJOR 2)
- set(Ruby_VERSION_MINOR 0)
+ string(REGEX_REPLACE ${Ruby_EXECUTABLE} "ruby2\\.?([0-7])" "\\1" Ruby_VERSION_MINOR)
endif()
- # check whether we found 2.1.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?1")
- set(Ruby_VERSION_MAJOR 2)
- set(Ruby_VERSION_MINOR 1)
- endif()
- # check whether we found 2.2.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?2")
- set(Ruby_VERSION_MAJOR 2)
- set(Ruby_VERSION_MINOR 2)
- endif()
- # check whether we found 2.3.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?3")
- set(Ruby_VERSION_MAJOR 2)
- set(Ruby_VERSION_MINOR 3)
- endif()
- # check whether we found 2.4.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?4")
- set(Ruby_VERSION_MAJOR 2)
- set(Ruby_VERSION_MINOR 4)
- endif()
- # check whether we found 2.5.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?5")
- set(Ruby_VERSION_MAJOR 2)
- set(Ruby_VERSION_MINOR 5)
- endif()
- # check whether we found 2.6.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?6")
- set(Ruby_VERSION_MAJOR 2)
- set(Ruby_VERSION_MINOR 6)
- endif()
- # check whether we found 2.7.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby2\\.?7")
- set(Ruby_VERSION_MAJOR 2)
- set(Ruby_VERSION_MINOR 7)
- endif()
- # check whether we found 3.0.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby3\\.?0")
- set(Ruby_VERSION_MAJOR 3)
- set(Ruby_VERSION_MINOR 0)
- endif()
- # check whether we found 3.1.x
- if(${Ruby_EXECUTABLE} MATCHES "ruby3\\.?1")
+ # check whether we found 3.[0-1].x
+ if(${Ruby_EXECUTABLE} MATCHES "ruby3")
set(Ruby_VERSION_MAJOR 3)
- set(Ruby_VERSION_MINOR 1)
+ string(REGEX_REPLACE ${Ruby_EXECUTABLE} "ruby3\\.?([0-1])" "\\1" Ruby_VERSION_MINOR)
endif()
+
endif()
if(Ruby_VERSION_MAJOR)
diff --git a/Modules/FindSDL_gfx.cmake b/Modules/FindSDL_gfx.cmake
new file mode 100644
index 0000000..2dd96e9
--- /dev/null
+++ b/Modules/FindSDL_gfx.cmake
@@ -0,0 +1,86 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindSDL_gfx
+-----------
+
+.. versionadded:: 3.25
+
+Locate SDL_gfx library
+
+This module defines:
+
+::
+
+ SDL::SDL_gfx, the name of the target to use with target_*() commands
+ SDL_GFX_LIBRARIES, the name of the library to link against
+ SDL_GFX_INCLUDE_DIRS, where to find the headers
+ SDL_GFX_FOUND, if false, do not try to link against
+ SDL_GFX_VERSION_STRING - human-readable string containing the
+ version of SDL_gfx
+
+``$SDLDIR`` is an environment variable that would correspond to the
+``./configure --prefix=$SDLDIR`` used in building SDL.
+#]=======================================================================]
+
+find_path(SDL_GFX_INCLUDE_DIRS
+ NAMES
+ SDL_framerate.h
+ SDL_gfxBlitFunc.h
+ SDL_gfxPrimitives.h
+ SDL_gfxPrimitives_font.h
+ SDL_imageFilter.h
+ SDL_rotozoom.h
+ HINTS
+ ENV SDLGFXDIR
+ ENV SDLDIR
+ PATH_SUFFIXES SDL
+ # path suffixes to search inside ENV{SDLDIR}
+ include/SDL include/SDL12 include/SDL11 include
+)
+
+if(CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(VC_LIB_PATH_SUFFIX lib/x64)
+else()
+ set(VC_LIB_PATH_SUFFIX lib/x86)
+endif()
+
+find_library(SDL_GFX_LIBRARIES
+ NAMES SDL_gfx
+ HINTS
+ ENV SDLGFXDIR
+ ENV SDLDIR
+ PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
+)
+
+if(SDL_GFX_INCLUDE_DIRS AND EXISTS "${SDL_GFX_INCLUDE_DIRS}/SDL_gfxPrimitives.h")
+ file(STRINGS "${SDL_GFX_INCLUDE_DIRS}/SDL_gfxPrimitives.h" SDL_GFX_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_GFXPRIMITIVES_MAJOR[ \t]+[0-9]+$")
+ file(STRINGS "${SDL_GFX_INCLUDE_DIRS}/SDL_gfxPrimitives.h" SDL_GFX_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_GFXPRIMITIVES_MINOR[ \t]+[0-9]+$")
+ file(STRINGS "${SDL_GFX_INCLUDE_DIRS}/SDL_gfxPrimitives.h" SDL_GFX_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_GFXPRIMITIVES_MICRO[ \t]+[0-9]+$")
+ string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MAJOR[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_MAJOR "${SDL_GFX_VERSION_MAJOR_LINE}")
+ string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MINOR[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_MINOR "${SDL_GFX_VERSION_MINOR_LINE}")
+ string(REGEX REPLACE "^#define[ \t]+SDL_GFXPRIMITIVES_MICRO[ \t]+([0-9]+)$" "\\1" SDL_GFX_VERSION_PATCH "${SDL_GFX_VERSION_PATCH_LINE}")
+ set(SDL_GFX_VERSION_STRING ${SDL_GFX_VERSION_MAJOR}.${SDL_GFX_VERSION_MINOR}.${SDL_GFX_VERSION_PATCH})
+ unset(SDL_GFX_VERSION_MAJOR_LINE)
+ unset(SDL_GFX_VERSION_MINOR_LINE)
+ unset(SDL_GFX_VERSION_PATCH_LINE)
+ unset(SDL_GFX_VERSION_MAJOR)
+ unset(SDL_GFX_VERSION_MINOR)
+ unset(SDL_GFX_VERSION_PATCH)
+endif()
+
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL_gfx
+ REQUIRED_VARS SDL_GFX_LIBRARIES SDL_GFX_INCLUDE_DIRS
+ VERSION_VAR SDL_GFX_VERSION_STRING)
+
+if(SDL_gfx_FOUND)
+ if(NOT TARGET SDL::SDL_gfx)
+ add_library(SDL::SDL_gfx INTERFACE IMPORTED)
+ set_target_properties(SDL::SDL_gfx PROPERTIES
+ INTERFACE_INCLUDE_DIRECTORIES "${SDL_GFX_INCLUDE_DIRS}"
+ INTERFACE_LINK_LIBRARIES "${SDL_GFX_LIBRARIES}")
+ endif()
+endif()
diff --git a/Modules/FindSDL_image.cmake b/Modules/FindSDL_image.cmake
index e687b49..324fef5 100644
--- a/Modules/FindSDL_image.cmake
+++ b/Modules/FindSDL_image.cmake
@@ -31,10 +31,6 @@ For backward compatibility the following variables are also set:
$SDLDIR is an environment variable that would correspond to the
./configure --prefix=$SDLDIR used in building SDL.
-
-Created by Eric Wing. This was influenced by the FindSDL.cmake
-module, but with modifications to recognize OS X frameworks and
-additional Unix paths (FreeBSD, etc).
#]=======================================================================]
if(NOT SDL_IMAGE_INCLUDE_DIR AND SDLIMAGE_INCLUDE_DIR)
diff --git a/Modules/FindSDL_mixer.cmake b/Modules/FindSDL_mixer.cmake
index 315400a..8ed3cb4 100644
--- a/Modules/FindSDL_mixer.cmake
+++ b/Modules/FindSDL_mixer.cmake
@@ -31,10 +31,6 @@ For backward compatibility the following variables are also set:
$SDLDIR is an environment variable that would correspond to the
./configure --prefix=$SDLDIR used in building SDL.
-
-Created by Eric Wing. This was influenced by the FindSDL.cmake
-module, but with modifications to recognize OS X frameworks and
-additional Unix paths (FreeBSD, etc).
#]=======================================================================]
if(NOT SDL_MIXER_INCLUDE_DIR AND SDLMIXER_INCLUDE_DIR)
diff --git a/Modules/FindSDL_net.cmake b/Modules/FindSDL_net.cmake
index 28cb4d6..639e5bd 100644
--- a/Modules/FindSDL_net.cmake
+++ b/Modules/FindSDL_net.cmake
@@ -30,10 +30,6 @@ For backward compatibility the following variables are also set:
$SDLDIR is an environment variable that would correspond to the
./configure --prefix=$SDLDIR used in building SDL.
-
-Created by Eric Wing. This was influenced by the FindSDL.cmake
-module, but with modifications to recognize OS X frameworks and
-additional Unix paths (FreeBSD, etc).
#]=======================================================================]
if(NOT SDL_NET_INCLUDE_DIR AND SDLNET_INCLUDE_DIR)
diff --git a/Modules/FindSDL_sound.cmake b/Modules/FindSDL_sound.cmake
index 8d2f9f8..6807522 100644
--- a/Modules/FindSDL_sound.cmake
+++ b/Modules/FindSDL_sound.cmake
@@ -54,7 +54,19 @@ Typically, you should not use these variables directly, and you should
use SDL_SOUND_LIBRARIES which contains SDL_SOUND_LIBRARY and the other
audio libraries (if needed) to successfully compile on your system.
-Created by Eric Wing. This module is a bit more complicated than the
+Responds to the $SDLDIR and $SDLSOUNDDIR environmental variable that
+would correspond to the ./configure --prefix=$SDLDIR used in building
+SDL.
+
+On OSX, this will prefer the Framework version (if found) over others.
+People will have to manually change the cache values of SDL_LIBRARY to
+override this selectionor set the CMake environment CMAKE_INCLUDE_PATH
+to modify the search paths.
+#]=======================================================================]
+
+
+#[[
+This module is a bit more complicated than the
other FindSDL* family modules. The reason is that SDL_sound can be
compiled in a large variety of different ways which are independent of
platform. SDL_sound may dynamically link against other 3rd party
@@ -70,16 +82,7 @@ This module uses a brute force approach to create a test program that
uses SDL_sound, and then tries to build it. If the build fails, it
parses the error output for known symbol names to figure out which
libraries are needed.
-
-Responds to the $SDLDIR and $SDLSOUNDDIR environmental variable that
-would correspond to the ./configure --prefix=$SDLDIR used in building
-SDL.
-
-On OSX, this will prefer the Framework version (if found) over others.
-People will have to manually change the cache values of SDL_LIBRARY to
-override this selectionor set the CMake environment CMAKE_INCLUDE_PATH
-to modify the search paths.
-#]=======================================================================]
+#]]
set(SDL_SOUND_EXTRAS "" CACHE STRING "SDL_sound extra flags")
mark_as_advanced(SDL_SOUND_EXTRAS)
diff --git a/Modules/FindSDL_ttf.cmake b/Modules/FindSDL_ttf.cmake
index d5721da..d67c089 100644
--- a/Modules/FindSDL_ttf.cmake
+++ b/Modules/FindSDL_ttf.cmake
@@ -30,10 +30,6 @@ For backward compatibility the following variables are also set:
$SDLDIR is an environment variable that would correspond to the
./configure --prefix=$SDLDIR used in building SDL.
-
-Created by Eric Wing. This was influenced by the FindSDL.cmake
-module, but with modifications to recognize OS X frameworks and
-additional Unix paths (FreeBSD, etc).
#]=======================================================================]
if(NOT SDL_TTF_INCLUDE_DIR AND SDLTTF_INCLUDE_DIR)
diff --git a/Modules/FindVulkan.cmake b/Modules/FindVulkan.cmake
index 7ca7d03..3817987 100644
--- a/Modules/FindVulkan.cmake
+++ b/Modules/FindVulkan.cmake
@@ -36,6 +36,11 @@ There are corresponding imported targets for each of these.
``MoltenVK``
On macOS, an additional component ``MoltenVK`` is available.
+``dxc``
+ .. versionadded:: 3.25
+
+ The DirectX Shader Compiler.
+
The ``glslc`` and ``glslangValidator`` components are provided even
if not explicitly requested (for backward compatibility).
@@ -89,6 +94,21 @@ This module defines :prop_tgt:`IMPORTED` targets if Vulkan has been found:
Defined if SDK has the Khronos library which implement a subset of Vulkan API
over Apple Metal graphics framework. (MoltenVK).
+``Vulkan::volk``
+ .. versionadded:: 3.25
+
+ Defined if SDK has the Vulkan meta-loader (volk).
+
+``Vulkan::dxc_lib``
+ .. versionadded:: 3.25
+
+ Defined if SDK has the DirectX shader compiler library.
+
+``Vulkan::dxc_exe``
+ .. versionadded:: 3.25
+
+ Defined if SDK has the DirectX shader compiler CLI tool.
+
Result Variables
^^^^^^^^^^^^^^^^
@@ -128,6 +148,21 @@ This module defines the following variables:
.. versionadded:: 3.24
True, if the SDK has the MoltenVK library.
+``Vulkan_volk_FOUND``
+ .. versionadded:: 3.25
+
+ True, if the SDK has the volk library.
+
+``Vulkan_dxc_lib_FOUND``
+ .. versionadded:: 3.25
+
+ True, if the SDK has the DirectX shader compiler library.
+
+``Vulkan_dxc_exe_FOUND``
+ .. versionadded:: 3.25
+
+ True, if the SDK has the DirectX shader compiler CLI tool.
+
The module will also defines these cache variables:
@@ -156,6 +191,21 @@ The module will also defines these cache variables:
Path to the MoltenVK library.
+``Vulkan_volk_LIBRARY``
+ .. versionadded:: 3.25
+
+ Path to the volk library.
+
+``Vulkan_dxc_LIBRARY``
+ .. versionadded:: 3.25
+
+ Path to the DirectX shader compiler library.
+
+``Vulkan_dxc_EXECUTABLE``
+ .. versionadded:: 3.25
+
+ Path to the DirectX shader compiler CLI tool.
+
Hints
^^^^^
@@ -403,6 +453,27 @@ if(MoltenVK IN_LIST Vulkan_FIND_COMPONENTS)
)
mark_as_advanced(Vulkan_MoltenVK_INCLUDE_DIR)
endif()
+if(volk IN_LIST Vulkan_FIND_COMPONENTS)
+ find_library(Vulkan_volk_LIBRARY
+ NAMES volk
+ HINTS
+ ${_Vulkan_hint_library_search_paths})
+ mark_as_advanced(Vulkan_Volk_LIBRARY)
+endif()
+
+if (dxc IN_LIST Vulkan_FIND_COMPONENTS)
+ find_library(Vulkan_dxc_LIBRARY
+ NAMES dxcompiler
+ HINTS
+ ${_Vulkan_hint_library_search_paths})
+ mark_as_advanced(Vulkan_dxc_LIBRARY)
+
+ find_program(Vulkan_dxc_EXECUTABLE
+ NAMES dxc
+ HINTS
+ ${_Vulkan_hint_executable_search_paths})
+ mark_as_advanced(Vulkan_dxc_EXECUTABLE)
+endif()
if(Vulkan_GLSLC_EXECUTABLE)
set(Vulkan_glslc_FOUND TRUE)
@@ -416,6 +487,12 @@ else()
set(Vulkan_glslangValidator_FOUND FALSE)
endif()
+if (Vulkan_dxc_EXECUTABLE)
+ set(Vulkan_dxc_exe_FOUND TRUE)
+else()
+ set(Vulkan_dxc_exe_FOUND FALSE)
+endif()
+
function(_Vulkan_set_library_component_found component)
cmake_parse_arguments(PARSE_ARGV 1 _ARG
"NO_WARNING"
@@ -466,6 +543,8 @@ _Vulkan_set_library_component_found(glslang
glslang-genericcodegen)
_Vulkan_set_library_component_found(shaderc_combined)
_Vulkan_set_library_component_found(SPIRV-Tools)
+_Vulkan_set_library_component_found(volk)
+_Vulkan_set_library_component_found(dxc)
if(Vulkan_MoltenVK_INCLUDE_DIR AND Vulkan_MoltenVK_LIBRARY)
set(Vulkan_MoltenVK_FOUND TRUE)
@@ -752,6 +831,44 @@ if(Vulkan_FOUND)
IMPORTED_LOCATION_DEBUG "${Vulkan_SPIRV-Tools_DEBUG_LIBRARY}")
endif()
endif()
+
+ if(Vulkan_volk_LIBRARY AND NOT TARGET Vulkan::volk)
+ add_library(Vulkan::volk STATIC IMPORTED)
+ set_property(TARGET Vulkan::volk
+ PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+ set_property(TARGET Vulkan::volk APPEND
+ PROPERTY
+ IMPORTED_CONFIGURATIONS Release)
+ set_property(TARGET Vulkan::volk APPEND
+ PROPERTY
+ IMPORTED_LOCATION_RELEASE "${Vulkan_volk_LIBRARY}")
+
+ if (NOT WIN32)
+ set_property(TARGET Vulkan::volk APPEND
+ PROPERTY
+ IMPORTED_LINK_INTERFACE_LIBRARIES dl)
+ endif()
+ endif()
+
+ if (Vulkan_dxc_LIBRARY AND NOT TARGET Vulkan::dxc_lib)
+ add_library(Vulkan::dxc_lib STATIC IMPORTED)
+ set_property(TARGET Vulkan::dxc_lib
+ PROPERTY
+ INTERFACE_INCLUDE_DIRECTORIES "${Vulkan_INCLUDE_DIRS}")
+ set_property(TARGET Vulkan::dxc_lib APPEND
+ PROPERTY
+ IMPORTED_CONFIGURATIONS Release)
+ set_property(TARGET Vulkan::dxc_lib APPEND
+ PROPERTY
+ IMPORTED_LOCATION_RELEASE "${Vulkan_dxc_LIBRARY}")
+ endif()
+
+ if(Vulkan_dxc_EXECUTABLE AND NOT TARGET Vulkan::dxc_exe)
+ add_executable(Vulkan::dxc_exe IMPORTED)
+ set_property(TARGET Vulkan::dxc_exe PROPERTY IMPORTED_LOCATION "${Vulkan_dxc_EXECUTABLE}")
+ endif()
+
endif()
if(Vulkan_MoltenVK_FOUND)
diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake
index 958a6db..38e32c2 100644
--- a/Modules/Internal/CPack/CPackDeb.cmake
+++ b/Modules/Internal/CPack/CPackDeb.cmake
@@ -37,8 +37,8 @@ endfunction()
#extract library name and version for given shared object
function(extract_so_info shared_object libname version)
- if(READELF_EXECUTABLE)
- execute_process(COMMAND "${READELF_EXECUTABLE}" -d "${shared_object}"
+ if(CPACK_READELF_EXECUTABLE)
+ execute_process(COMMAND "${CPACK_READELF_EXECUTABLE}" -d "${shared_object}"
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
RESULT_VARIABLE result
OUTPUT_VARIABLE output
@@ -197,15 +197,15 @@ function(cpack_deb_prepare_package_vars)
endforeach()
endif()
- find_program(READELF_EXECUTABLE NAMES readelf)
+ find_program(CPACK_READELF_EXECUTABLE NAMES readelf)
if(CPACK_DEBIAN_DEBUGINFO_PACKAGE AND CPACK_DEB_UNSTRIPPED_FILES)
- find_program(OBJCOPY_EXECUTABLE NAMES objcopy)
+ find_program(CPACK_OBJCOPY_EXECUTABLE NAMES objcopy)
- if(NOT OBJCOPY_EXECUTABLE)
+ if(NOT CPACK_OBJCOPY_EXECUTABLE)
message(FATAL_ERROR "debuginfo packages require the objcopy tool")
endif()
- if(NOT READELF_EXECUTABLE)
+ if(NOT CPACK_READELF_EXECUTABLE)
message(FATAL_ERROR "debuginfo packages require the readelf tool")
endif()
@@ -213,7 +213,7 @@ function(cpack_deb_prepare_package_vars)
foreach(_FILE IN LISTS CPACK_DEB_UNSTRIPPED_FILES)
# Get the file's Build ID
- execute_process(COMMAND env LC_ALL=C ${READELF_EXECUTABLE} -n "${_FILE}"
+ execute_process(COMMAND env LC_ALL=C ${CPACK_READELF_EXECUTABLE} -n "${_FILE}"
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
OUTPUT_VARIABLE READELF_OUTPUT
RESULT_VARIABLE READELF_RESULT
@@ -221,7 +221,7 @@ function(cpack_deb_prepare_package_vars)
OUTPUT_STRIP_TRAILING_WHITESPACE )
if(NOT READELF_RESULT EQUAL 0)
message(FATAL_ERROR "CPackDeb: readelf: '${READELF_ERROR}';\n"
- "executed command: '${READELF_EXECUTABLE} -n ${_FILE}'")
+ "executed command: '${CPACK_READELF_EXECUTABLE} -n ${_FILE}'")
endif()
if(READELF_OUTPUT MATCHES "Build ID: ([0-9a-zA-Z][0-9a-zA-Z])([0-9a-zA-Z]*)")
set(_BUILD_ID_START ${CMAKE_MATCH_1})
@@ -235,7 +235,7 @@ function(cpack_deb_prepare_package_vars)
set(_FILE_DBGSYM ${_DBGSYM_ROOT}/usr/lib/debug/.build-id/${_BUILD_ID_START}/${_BUILD_ID_REMAINING}.debug)
get_filename_component(_OUT_DIR "${_FILE_DBGSYM}" DIRECTORY)
file(MAKE_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}/${_OUT_DIR}")
- execute_process(COMMAND ${OBJCOPY_EXECUTABLE} --only-keep-debug "${_FILE}" "${_FILE_DBGSYM}"
+ execute_process(COMMAND ${CPACK_OBJCOPY_EXECUTABLE} --only-keep-debug "${_FILE}" "${_FILE_DBGSYM}"
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
OUTPUT_VARIABLE OBJCOPY_OUTPUT
RESULT_VARIABLE OBJCOPY_RESULT
@@ -243,9 +243,9 @@ function(cpack_deb_prepare_package_vars)
OUTPUT_STRIP_TRAILING_WHITESPACE )
if(NOT OBJCOPY_RESULT EQUAL 0)
message(FATAL_ERROR "CPackDeb: objcopy: '${OBJCOPY_ERROR}';\n"
- "executed command: '${OBJCOPY_EXECUTABLE} --only-keep-debug ${_FILE} ${_FILE_DBGSYM}'")
+ "executed command: '${CPACK_OBJCOPY_EXECUTABLE} --only-keep-debug ${_FILE} ${_FILE_DBGSYM}'")
endif()
- execute_process(COMMAND ${OBJCOPY_EXECUTABLE} --strip-unneeded ${_FILE}
+ execute_process(COMMAND ${CPACK_OBJCOPY_EXECUTABLE} --strip-unneeded ${_FILE}
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
OUTPUT_VARIABLE OBJCOPY_OUTPUT
RESULT_VARIABLE OBJCOPY_RESULT
@@ -253,9 +253,9 @@ function(cpack_deb_prepare_package_vars)
OUTPUT_STRIP_TRAILING_WHITESPACE )
if(NOT OBJCOPY_RESULT EQUAL 0)
message(FATAL_ERROR "CPackDeb: objcopy: '${OBJCOPY_ERROR}';\n"
- "executed command: '${OBJCOPY_EXECUTABLE} --strip-debug ${_FILE}'")
+ "executed command: '${CPACK_OBJCOPY_EXECUTABLE} --strip-debug ${_FILE}'")
endif()
- execute_process(COMMAND ${OBJCOPY_EXECUTABLE} --add-gnu-debuglink=${_FILE_DBGSYM} ${_FILE}
+ execute_process(COMMAND ${CPACK_OBJCOPY_EXECUTABLE} --add-gnu-debuglink=${_FILE_DBGSYM} ${_FILE}
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
OUTPUT_VARIABLE OBJCOPY_OUTPUT
RESULT_VARIABLE OBJCOPY_RESULT
@@ -263,7 +263,7 @@ function(cpack_deb_prepare_package_vars)
OUTPUT_STRIP_TRAILING_WHITESPACE )
if(NOT OBJCOPY_RESULT EQUAL 0)
message(FATAL_ERROR "CPackDeb: objcopy: '${OBJCOPY_ERROR}';\n"
- "executed command: '${OBJCOPY_EXECUTABLE} --add-gnu-debuglink=${_FILE_DBGSYM} ${_FILE}'")
+ "executed command: '${CPACK_OBJCOPY_EXECUTABLE} --add-gnu-debuglink=${_FILE_DBGSYM} ${_FILE}'")
endif()
endforeach()
endif()
@@ -652,7 +652,7 @@ function(cpack_deb_prepare_package_vars)
unset(CPACK_DEBIAN_PACKAGE_SHLIBS_LIST)
if(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS)
- if(READELF_EXECUTABLE)
+ if(CPACK_READELF_EXECUTABLE)
foreach(_FILE IN LISTS CPACK_DEB_SHARED_OBJECT_FILES)
extract_so_info("${_FILE}" libname soversion)
if(libname AND DEFINED soversion)
diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake
index cd631b8..7c10280 100644
--- a/Modules/Internal/CPack/CPackRPM.cmake
+++ b/Modules/Internal/CPack/CPackRPM.cmake
@@ -625,8 +625,8 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
endif()
# With objdump we should check the debug symbols
- find_program(OBJDUMP_EXECUTABLE objdump)
- if(NOT OBJDUMP_EXECUTABLE)
+ find_program(CPACK_OBJDUMP_EXECUTABLE objdump)
+ if(NOT CPACK_OBJDUMP_EXECUTABLE)
message(FATAL_ERROR "CPackRPM: objdump binary could not be found!"
" Required for debuginfo packaging. See documentation of"
" CPACK_RPM_DEBUGINFO_PACKAGE variable for details.")
@@ -649,7 +649,7 @@ function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR)
continue()
endif()
- execute_process(COMMAND "${OBJDUMP_EXECUTABLE}" -h ${WORKING_DIR}/${F}
+ execute_process(COMMAND "${CPACK_OBJDUMP_EXECUTABLE}" -h ${WORKING_DIR}/${F}
WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}"
RESULT_VARIABLE OBJDUMP_EXEC_RESULT
OUTPUT_VARIABLE OBJDUMP_OUT
diff --git a/Modules/Platform/AIX-GNU.cmake b/Modules/Platform/AIX-GNU.cmake
index 5a532c7..a9aa8e0 100644
--- a/Modules/Platform/AIX-GNU.cmake
+++ b/Modules/Platform/AIX-GNU.cmake
@@ -23,11 +23,11 @@ macro(__aix_compiler_gnu lang)
# Construct the export list ourselves to pass only the object files so
# that we export only the symbols actually provided by the sources.
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
- "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp <AIX_EXPORTS> <OBJECTS>"
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp -c <CMAKE_${lang}_COMPILER> <AIX_EXPORTS> <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/exports.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS
- "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <AIX_EXPORTS> <OBJECTS>"
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -c <CMAKE_${lang}_COMPILER> -l . <AIX_EXPORTS> <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
endmacro()
diff --git a/Modules/Platform/AIX-XL.cmake b/Modules/Platform/AIX-XL.cmake
index 2a8c159..902cbb3 100644
--- a/Modules/Platform/AIX-XL.cmake
+++ b/Modules/Platform/AIX-XL.cmake
@@ -29,12 +29,12 @@ macro(__aix_compiler_xl lang)
# Construct the export list ourselves to pass only the object files so
# that we export only the symbols actually provided by the sources.
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
- "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp <AIX_EXPORTS>${_OBJECTS}"
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <OBJECT_DIR>/exports.exp -c <CMAKE_${lang}_COMPILER> <AIX_EXPORTS>${_OBJECTS}"
"<CMAKE_${lang}_COMPILER> <CMAKE_SHARED_LIBRARY_${lang}_FLAGS> -Wl,-bE:<OBJECT_DIR>/exports.exp <LANGUAGE_COMPILE_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
)
set(CMAKE_${lang}_LINK_EXECUTABLE_WITH_EXPORTS
- "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -l . <AIX_EXPORTS> <OBJECTS>"
+ "\"${CMAKE_ROOT}/Modules/Platform/AIX/ExportImportList\" -o <TARGET_IMPLIB> -c <CMAKE_${lang}_COMPILER> -l . <AIX_EXPORTS> <OBJECTS>"
"<CMAKE_${lang}_COMPILER> <FLAGS> <CMAKE_${lang}_LINK_FLAGS> -Wl,-bE:<TARGET_IMPLIB> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
unset(_OBJECTS)
diff --git a/Modules/Platform/AIX/ExportImportList b/Modules/Platform/AIX/ExportImportList
index 891bce7..5e16fcb 100755
--- a/Modules/Platform/AIX/ExportImportList
+++ b/Modules/Platform/AIX/ExportImportList
@@ -5,7 +5,7 @@
# This script is internal to CMake and meant only to be
# invoked by CMake-generated build systems on AIX.
-usage='usage: ExportImportList -o <out-file> [-l <lib>] [-n] [--] <objects>...'
+usage='usage: ExportImportList -o <out-file> -c <compiler> [-l <lib>] [-n] [--] <objects>...'
die() {
echo "$@" 1>&2; exit 1
@@ -15,11 +15,13 @@ die() {
out=''
lib=''
no_objects=''
+compiler=''
while test "$#" != 0; do
case "$1" in
-l) shift; lib="$1" ;;
-o) shift; out="$1" ;;
-n) no_objects='1' ;;
+ -c) shift; compiler="$1" ;;
--) shift; break ;;
-*) die "$usage" ;;
*) break ;;
@@ -27,27 +29,47 @@ while test "$#" != 0; do
shift
done
test -n "$out" || die "$usage"
+# We need the compiler executable to resolve where the ibm-llvm-nm executable is
+test -n "$compiler" || die "$usage"
# Build a temporary file that atomically replaces the output later.
out_tmp="$out.tmp$$"
trap 'rm -f "$out_tmp"' EXIT INT TERM
> "$out_tmp"
+# If IPA was enabled and a compiler from the IBMClang family is used, then
+# the object files contain LLVM bitcode[0] rather than XCOFF objects and so
+# need to be handled differently.
+#
+# [0]: https://www.ibm.com/docs/en/openxl-c-and-cpp-aix/17.1.0?topic=compatibility-link-time-optimization-lto
+NM="$(dirname "$compiler")/../libexec/ibm-llvm-nm"
+
+function IsBitcode {
+ # N4 = first 4 bytes, -tx = output in hexadecimal, -An = don't display offset
+ # cut: trim off the preceding whitespace where the offset would be
+ # 4243code is the hexadecimal magic number for LLVM bitcode
+ [ "$(od -N4 -tx -An $1 | cut -d ' ' -f 2)" == "4243c0de" ];
+}
+
# Collect symbols exported from all object files.
if test -z "$no_objects"; then
for f in "$@"; do
- dump -tov -X 32_64 "$f" |
- awk '
- BEGIN {
- V["EXPORTED"]=" export"
- V["PROTECTED"]=" protected"
- }
- /^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|bss) +[^ ]+ +(extern|weak) +(EXPORTED|PROTECTED| ) / {
- if (!match($NF,/^(\.|__sinit|__sterm|__[0-9]+__)/)) {
- print $NF V[$(NF-1)]
+ if IsBitcode "$f"; then
+ "$NM" "$f" --defined-only --extern-only --just-symbol-name 2>/dev/null
+ else
+ dump -tov -X 32_64 "$f" |
+ awk '
+ BEGIN {
+ V["EXPORTED"]=" export"
+ V["PROTECTED"]=" protected"
+ }
+ /^\[[0-9]+\]\tm +[^ ]+ +\.(text|data|bss) +[^ ]+ +(extern|weak) +(EXPORTED|PROTECTED| ) / {
+ if (!match($NF,/^(\.|__sinit|__sterm|__[0-9]+__)/)) {
+ print $NF V[$(NF-1)]
+ }
}
- }
- '
+ '
+ fi
done >> "$out_tmp"
fi
diff --git a/Modules/Platform/DragonFly.cmake b/Modules/Platform/DragonFly.cmake
index 12e5f3c..d8bc05a 100644
--- a/Modules/Platform/DragonFly.cmake
+++ b/Modules/Platform/DragonFly.cmake
@@ -3,6 +3,8 @@
# see http://archive.netbsd.se/?ml=dfbsd-users&a=2007-07&m=4678361
include(Platform/FreeBSD)
+unset(FREEBSD)
+set(DRAGONFLYBSD 1)
# DragonFly BSD requires -z origin to enable $ORIGIN expansion in RPATH.
# This is not required for FreeBSD since 10.2-RELEASE.
diff --git a/Modules/Platform/FreeBSD.cmake b/Modules/Platform/FreeBSD.cmake
index bd5a786..e968a78 100644
--- a/Modules/Platform/FreeBSD.cmake
+++ b/Modules/Platform/FreeBSD.cmake
@@ -1,3 +1,5 @@
+set(FREEBSD 1)
+set(BSD 1)
set(CMAKE_DL_LIBS "")
set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
diff --git a/Modules/Platform/Linux-IntelLLVM.cmake b/Modules/Platform/Linux-IntelLLVM.cmake
index 1363b44..992f80e 100644
--- a/Modules/Platform/Linux-IntelLLVM.cmake
+++ b/Modules/Platform/Linux-IntelLLVM.cmake
@@ -8,18 +8,6 @@ if(__LINUX_COMPILER_INTEL_LLVM)
endif()
set(__LINUX_COMPILER_INTEL_LLVM 1)
-if(NOT XIAR)
- set(_intel_xiar_hints)
- foreach(lang C CXX Fortran)
- if(IS_ABSOLUTE "${CMAKE_${lang}_COMPILER}")
- get_filename_component(_hint "${CMAKE_${lang}_COMPILER}" PATH)
- list(APPEND _intel_xiar_hints ${_hint})
- endif()
- endforeach()
- find_program(XIAR NAMES xiar HINTS ${_intel_xiar_hints})
- mark_as_advanced(XIAR)
-endif()
-
macro(__linux_compiler_intel_llvm lang)
set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
@@ -37,19 +25,5 @@ macro(__linux_compiler_intel_llvm lang)
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "-Wl,")
set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP ",")
- set(_CMAKE_${lang}_IPO_SUPPORTED_BY_CMAKE YES)
-
- if(XIAR)
- # INTERPROCEDURAL_OPTIMIZATION
- set(CMAKE_${lang}_COMPILE_OPTIONS_IPO -ipo)
- set(CMAKE_${lang}_CREATE_STATIC_LIBRARY_IPO
- "${XIAR} cr <TARGET> <LINK_FLAGS> <OBJECTS> "
- "${XIAR} -s <TARGET> ")
- set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER YES)
- set(_CMAKE_${lang}_IPO_LEGACY_BEHAVIOR YES)
- else()
- set(_CMAKE_${lang}_IPO_MAY_BE_SUPPORTED_BY_COMPILER NO)
- endif()
-
set(CMAKE_${lang}_COMPILE_OPTIONS_VISIBILITY "-fvisibility=")
endmacro()
diff --git a/Modules/Platform/Linux-NVHPC.cmake b/Modules/Platform/Linux-NVHPC.cmake
index aad17f1..602b417 100644
--- a/Modules/Platform/Linux-NVHPC.cmake
+++ b/Modules/Platform/Linux-NVHPC.cmake
@@ -3,13 +3,15 @@
# This module is shared by multiple languages; use include blocker.
-if(__LINUX_COMPILER_NVIDIA)
- return()
-endif()
-set(__LINUX_COMPILER_NVIDIA 1)
-
-include(Platform/Linux-PGI)
+include_guard()
macro(__linux_compiler_nvhpc lang)
- __linux_compiler_pgi(${lang})
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIC "-fPIC")
+ set(CMAKE_${lang}_COMPILE_OPTIONS_PIE "-fPIE")
+ set(_CMAKE_${lang}_PIE_MAY_BE_SUPPORTED_BY_LINKER YES)
+ set(CMAKE_${lang}_LINK_OPTIONS_PIE "-fPIE")
+ set(CMAKE_${lang}_LINK_OPTIONS_NO_PIE "")
+ set(CMAKE_SHARED_LIBRARY_${lang}_FLAGS "-fPIC")
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared")
+ set(CMAKE_SHARED_LIBRARY_LINK_${lang}_FLAGS "")
endmacro()
diff --git a/Modules/Platform/Linux.cmake b/Modules/Platform/Linux.cmake
index a7e58ab..e3d444e 100644
--- a/Modules/Platform/Linux.cmake
+++ b/Modules/Platform/Linux.cmake
@@ -1,3 +1,4 @@
+set(LINUX 1)
set(CMAKE_DL_LIBS "dl")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,")
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG_SEP ":")
diff --git a/Modules/Platform/NetBSD.cmake b/Modules/Platform/NetBSD.cmake
index ab85923..a64bf0b 100644
--- a/Modules/Platform/NetBSD.cmake
+++ b/Modules/Platform/NetBSD.cmake
@@ -1,3 +1,5 @@
+set(NETBSD 1)
+set(BSD 1)
set(CMAKE_DL_LIBS "")
set(CMAKE_C_COMPILE_OPTIONS_PIC "-fPIC")
set(CMAKE_C_COMPILE_OPTIONS_PIE "-fPIE")
diff --git a/Modules/Platform/OpenBSD.cmake b/Modules/Platform/OpenBSD.cmake
index 97e2a6a..f6b955a 100644
--- a/Modules/Platform/OpenBSD.cmake
+++ b/Modules/Platform/OpenBSD.cmake
@@ -1,4 +1,6 @@
include(Platform/NetBSD)
+unset(NETBSD)
+set(OPENBSD 1)
# On OpenBSD, the compile time linker does not share it's configuration with
# the runtime linker. This will extract the library search paths from the
diff --git a/Modules/Platform/SerenityOS-Clang-ASM.cmake b/Modules/Platform/SerenityOS-Clang-ASM.cmake
new file mode 100644
index 0000000..ba1e18c
--- /dev/null
+++ b/Modules/Platform/SerenityOS-Clang-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/SerenityOS-GNU)
+__serenity_compiler_gnu(ASM)
diff --git a/Modules/Platform/SerenityOS-Clang-C.cmake b/Modules/Platform/SerenityOS-Clang-C.cmake
new file mode 100644
index 0000000..791a197
--- /dev/null
+++ b/Modules/Platform/SerenityOS-Clang-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/SerenityOS-GNU)
+__serenity_compiler_gnu(C)
diff --git a/Modules/Platform/SerenityOS-Clang-CXX.cmake b/Modules/Platform/SerenityOS-Clang-CXX.cmake
new file mode 100644
index 0000000..084e319
--- /dev/null
+++ b/Modules/Platform/SerenityOS-Clang-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/SerenityOS-GNU)
+__serenity_compiler_gnu(CXX)
diff --git a/Modules/Platform/SerenityOS-GNU-ASM.cmake b/Modules/Platform/SerenityOS-GNU-ASM.cmake
new file mode 100644
index 0000000..ba1e18c
--- /dev/null
+++ b/Modules/Platform/SerenityOS-GNU-ASM.cmake
@@ -0,0 +1,2 @@
+include(Platform/SerenityOS-GNU)
+__serenity_compiler_gnu(ASM)
diff --git a/Modules/Platform/SerenityOS-GNU-C.cmake b/Modules/Platform/SerenityOS-GNU-C.cmake
new file mode 100644
index 0000000..791a197
--- /dev/null
+++ b/Modules/Platform/SerenityOS-GNU-C.cmake
@@ -0,0 +1,2 @@
+include(Platform/SerenityOS-GNU)
+__serenity_compiler_gnu(C)
diff --git a/Modules/Platform/SerenityOS-GNU-CXX.cmake b/Modules/Platform/SerenityOS-GNU-CXX.cmake
new file mode 100644
index 0000000..084e319
--- /dev/null
+++ b/Modules/Platform/SerenityOS-GNU-CXX.cmake
@@ -0,0 +1,2 @@
+include(Platform/SerenityOS-GNU)
+__serenity_compiler_gnu(CXX)
diff --git a/Modules/Platform/SerenityOS-GNU.cmake b/Modules/Platform/SerenityOS-GNU.cmake
new file mode 100644
index 0000000..ed39477
--- /dev/null
+++ b/Modules/Platform/SerenityOS-GNU.cmake
@@ -0,0 +1,24 @@
+# This module is shared by multiple languages; use include blocker.
+include_guard()
+
+set(CMAKE_EXE_LINKER_FLAGS_INIT "-Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,separate-code,-z,max-page-size=0x1000")
+
+macro(__serenity_compiler_gnu lang)
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG "-Wl,-rpath,")
+ set(CMAKE_SHARED_LIBRARY_RUNTIME_${lang}_FLAG_SEP ":")
+ set(CMAKE_SHARED_LIBRARY_RPATH_LINK_${lang}_FLAG "-Wl,-rpath-link,")
+ set(CMAKE_SHARED_LIBRARY_SONAME_${lang}_FLAG "-Wl,-soname,")
+ set(CMAKE_EXE_EXPORTS_${lang}_FLAG "-Wl,--export-dynamic")
+
+ set(CMAKE_SHARED_LIBRARY_CREATE_${lang}_FLAGS "-shared -Wl,--hash-style=gnu,-z,relro,-z,now,-z,noexecstack,-z,separate-code")
+
+ # Initialize link type selection flags. These flags are used when
+ # building a shared library, shared module, or executable that links
+ # to other libraries to select whether to use the static or shared
+ # versions of the libraries.
+ foreach(type SHARED_LIBRARY SHARED_MODULE EXE)
+ set(CMAKE_${type}_LINK_STATIC_${lang}_FLAGS "-Wl,-Bstatic")
+ set(CMAKE_${type}_LINK_DYNAMIC_${lang}_FLAGS "-Wl,-Bdynamic")
+ endforeach()
+
+endmacro()
diff --git a/Modules/Platform/SerenityOS.cmake b/Modules/Platform/SerenityOS.cmake
new file mode 100644
index 0000000..541620c
--- /dev/null
+++ b/Modules/Platform/SerenityOS.cmake
@@ -0,0 +1,12 @@
+
+set(SERENITYOS 1)
+
+set(CMAKE_DL_LIBS "-ldl")
+set(CMAKE_SHARED_LIBRARY_RPATH_ORIGIN_TOKEN "\$ORIGIN")
+set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
+
+# Shared libraries with no builtin soname may not be linked safely by
+# specifying the file path.
+set(CMAKE_PLATFORM_USES_PATH_WHEN_NO_SONAME 1)
+
+include(Platform/UnixPaths)
diff --git a/Modules/Platform/Windows-IntelLLVM.cmake b/Modules/Platform/Windows-IntelLLVM.cmake
index f24dcdb..43f5874 100644
--- a/Modules/Platform/Windows-IntelLLVM.cmake
+++ b/Modules/Platform/Windows-IntelLLVM.cmake
@@ -3,26 +3,61 @@
# This module is shared by multiple languages; use include blocker.
-if(__WINDOWS_INTEL)
+if(__WINDOWS_INTEL_LLVM)
return()
endif()
-set(__WINDOWS_INTEL 1)
+set(__WINDOWS_INTEL_LLVM 1)
+# Platform/Windows-MSVC adds some linking options icx/ifx do not understand,
+# but that need to be passed to the linker. Wrap all the linking options from
+# Platform/Windows-MSVC so that the compiler will hand them off to the linker
+# without interpreting them.
+
+# Save original CMAKE_${t}_LINKER_FLAGS_INIT
+foreach(t EXE SHARED MODULE STATIC)
+ set(_saved_cmake_${t}_linker_flags_init ${CMAKE_${t}_LINKER_FLAGS_INIT})
+ set(CMAKE_${t}_LINKER_FLAGS_INIT "")
+endforeach()
include(Platform/Windows-MSVC)
+# Wrap linker flags from Windows-MSVC
+set(_IntelLLVM_LINKER_WRAPPER_FLAG "/Qoption,link,")
+set(_IntelLLVM_LINKER_WRAPPER_FLAG_SEP ",")
+foreach(t EXE SHARED MODULE STATIC)
+ set(_wrapped_linker_flags "")
+ foreach(flag ${CMAKE_${t}_LINKER_FLAGS_INIT})
+ string(STRIP ${flag} flag)
+ list(APPEND _wrapped_linker_flags "${_IntelLLVM_LINKER_WRAPPER_FLAG}${flag}")
+ endforeach()
+ set(CMAKE_${t}_LINKER_FLAGS_INIT "")
+ list(APPEND CMAKE_${t}_LINKER_FLAGS_INIT
+ ${_saved_cmake_${t}_linker_flags_init} ${_wrapped_linker_flags})
+endforeach()
+
macro(__windows_compiler_intel lang)
__windows_compiler_msvc(${lang})
- # For DPCPP other offload cases, some link flags need to go to the compiler
- # driver and others need to go to the linker. Pass the compiler linking flags
- # in CMAKE_${lang}_LINK_FLAGS and linker flags in LINK_FLAGS
+ set(CMAKE_${lang}_LINKER_WRAPPER_FLAG "${_IntelLLVM_LINKER_WRAPPER_FLAG}")
+ set(CMAKE_${lang}_LINKER_WRAPPER_FLAG_SEP "${_IntelLLVM_LINKER_WRAPPER_FLAG_SEP}")
+ set(CMAKE_${lang}_CREATE_WIN32_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:windows")
+ set(CMAKE_${lang}_CREATE_CONSOLE_EXE "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/subsystem:console")
+ set(CMAKE_LINK_DEF_FILE_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/DEF:")
+ set(CMAKE_LIBRARY_PATH_FLAG "${CMAKE_${lang}_LINKER_WRAPPER_FLAG}/LIBPATH:")
+
+ # Features for LINK_LIBRARY generator expression
+ if(MSVC_VERSION GREATER "1900")
+ ## WHOLE_ARCHIVE: Force loading all members of an archive
+ set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE "LINKER:/WHOLEARCHIVE:<LIBRARY>")
+ set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED TRUE)
+ endif()
+
set(CMAKE_${lang}_LINK_EXECUTABLE
- "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} /link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES>${CMAKE_END_TEMP_FILE}")
+ "${_CMAKE_VS_LINK_EXE}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} <LINK_FLAGS> <LINK_LIBRARIES> /link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} ${CMAKE_END_TEMP_FILE}")
set(CMAKE_${lang}_CREATE_SHARED_LIBRARY
- "${_CMAKE_VS_LINK_DLL}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -LD -link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "${_CMAKE_VS_LINK_DLL}<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -LD <LINK_FLAGS> <LINK_LIBRARIES> -link /out:<TARGET> /implib:<TARGET_IMPLIB> /pdb:<TARGET_PDB> /version:<TARGET_VERSION_MAJOR>.<TARGET_VERSION_MINOR>${_PLATFORM_LINK_FLAGS} ${CMAKE_END_TEMP_FILE}")
if (NOT "${lang}" STREQUAL "Fortran" OR CMAKE_${lang}_COMPILER_VERSION VERSION_GREATER_EQUAL 2022.1)
# The Fortran driver does not support -fuse-ld=llvm-lib before compiler version 2022.1
set(CMAKE_${lang}_CREATE_STATIC_LIBRARY
- "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -fuse-ld=llvm-lib -o <TARGET> -link <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
+ "<CMAKE_${lang}_COMPILER> ${CMAKE_CL_NOLOGO} <CMAKE_${lang}_LINK_FLAGS> <OBJECTS> ${CMAKE_START_TEMP_FILE} -fuse-ld=llvm-lib -o <TARGET> <LINK_FLAGS> <LINK_LIBRARIES> ${CMAKE_END_TEMP_FILE}")
endif()
set(CMAKE_DEPFILE_FLAGS_${lang} "-QMD -QMT <DEP_TARGET> -QMF <DEP_FILE>")
diff --git a/Modules/Platform/kFreeBSD.cmake b/Modules/Platform/kFreeBSD.cmake
index c1db259..09c240d 100644
--- a/Modules/Platform/kFreeBSD.cmake
+++ b/Modules/Platform/kFreeBSD.cmake
@@ -1,4 +1,5 @@
-# kFreeBSD looks just like Linux.
+# kFreeBSD is a Debian GNU distribution with a kernel from FreeBSD,
+# and should be marked as LINUX
include(Platform/Linux)
set(CMAKE_LIBRARY_ARCHITECTURE_REGEX "[a-z0-9_]+(-[a-z0-9_]+)?-kfreebsd-gnu[a-z0-9_]*")
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index 95b07cb..86f8116 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -168,6 +168,7 @@ set(SRCS
cmCMakePresetsGraphReadJSON.cxx
cmCMakePresetsGraphReadJSONBuildPresets.cxx
cmCMakePresetsGraphReadJSONConfigurePresets.cxx
+ cmCMakePresetsGraphReadJSONPackagePresets.cxx
cmCMakePresetsGraphReadJSONTestPresets.cxx
cmCommandArgumentParserHelper.cxx
cmCommonTargetGenerator.cxx
@@ -197,6 +198,8 @@ set(SRCS
cmCustomCommandLines.cxx
cmCustomCommandLines.h
cmCustomCommandTypes.h
+ cmCxxModuleMapper.cxx
+ cmCxxModuleMapper.h
cmDefinitions.cxx
cmDefinitions.h
cmDependencyProvider.h
@@ -543,6 +546,8 @@ set(SRCS
cmExecuteProcessCommand.h
cmExpandedCommandArgument.cxx
cmExpandedCommandArgument.h
+ cmExperimental.cxx
+ cmExperimental.h
cmExportCommand.cxx
cmExportCommand.h
cmExportLibraryDependenciesCommand.cxx
@@ -567,6 +572,8 @@ set(SRCS
cmFindProgramCommand.h
cmForEachCommand.cxx
cmForEachCommand.h
+ cmBlockCommand.cxx
+ cmBlockCommand.h
cmFunctionBlocker.cxx
cmFunctionBlocker.h
cmFunctionCommand.cxx
@@ -603,6 +610,8 @@ set(SRCS
cmInstallCommand.h
cmInstallCommandArguments.cxx
cmInstallCommandArguments.h
+ cmInstallCxxModuleBmiGenerator.cxx
+ cmInstallCxxModuleBmiGenerator.h
cmInstallFilesCommand.cxx
cmInstallFilesCommand.h
cmInstallProgramsCommand.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 6851aa2..de9c261 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 24)
-set(CMake_VERSION_PATCH 1)
+set(CMake_VERSION_PATCH 20220909)
#set(CMake_VERSION_RC 0)
set(CMake_VERSION_IS_DIRTY 0)
diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx
index 56e8463..894c24b 100644
--- a/Source/CPack/cmCPackArchiveGenerator.cxx
+++ b/Source/CPack/cmCPackArchiveGenerator.cxx
@@ -94,6 +94,18 @@ std::string cmCPackArchiveGenerator::GetArchiveComponentFileName(
int cmCPackArchiveGenerator::InitializeInternal()
{
this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1");
+ cmValue newExtensionValue = this->GetOption("CPACK_ARCHIVE_FILE_EXTENSION");
+ if (!newExtensionValue.IsEmpty()) {
+ std::string newExtension = *newExtensionValue;
+ if (!cmHasLiteralPrefix(newExtension, ".")) {
+ newExtension = cmStrCat('.', newExtension);
+ }
+ cmCPackLogger(cmCPackLog::LOG_DEBUG,
+ "Using user-provided file extension "
+ << newExtension << " instead of the default "
+ << this->OutputExtension << std::endl);
+ this->OutputExtension = std::move(newExtension);
+ }
return this->Superclass::InitializeInternal();
}
diff --git a/Source/CPack/cmCPackFreeBSDGenerator.cxx b/Source/CPack/cmCPackFreeBSDGenerator.cxx
index 607d797..162dfc7 100644
--- a/Source/CPack/cmCPackFreeBSDGenerator.cxx
+++ b/Source/CPack/cmCPackFreeBSDGenerator.cxx
@@ -23,8 +23,6 @@
// Suffix used to tell libpkg what compression to use
static const char FreeBSDPackageCompression[] = "txz";
-// Resulting package file-suffix, for < 1.17 and >= 1.17 versions of libpkg
-static const char FreeBSDPackageSuffix_10[] = ".txz";
static const char FreeBSDPackageSuffix_17[] = ".pkg";
cmCPackFreeBSDGenerator::cmCPackFreeBSDGenerator()
@@ -83,6 +81,14 @@ public:
{
if (!isValid())
return false;
+ // The API in the FreeBSD sources (the header has no documentation),
+ // is as follows:
+ //
+ // int pkg_create(struct pkg_create *pc, const char *metadata, const char
+ // *plist, bool hash)
+ //
+ // We let the plist be determined from what is installed, and all
+ // the rest comes from the manifest data.
int r = pkg_create(d, manifest.c_str(), nullptr, false);
return r == 0;
}
@@ -402,7 +408,8 @@ int cmCPackFreeBSDGenerator::PackageFiles()
return 0;
}
- std::string output_dir = cmSystemTools::CollapseFullPath("../", toplevel);
+ const std::string output_dir =
+ cmSystemTools::CollapseFullPath("../", toplevel);
PkgCreate package(output_dir, toplevel, manifestname);
if (package.isValid()) {
if (!package.Create()) {
@@ -416,40 +423,33 @@ int cmCPackFreeBSDGenerator::PackageFiles()
return 0;
}
- // Specifically looking for packages suffixed with the TAG, either extension
- std::string broken_suffix_10 =
- cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), FreeBSDPackageSuffix_10);
+ // Specifically looking for packages suffixed with the TAG
std::string broken_suffix_17 =
cmStrCat('-', var_lookup("CPACK_TOPLEVEL_TAG"), FreeBSDPackageSuffix_17);
for (std::string& name : packageFileNames) {
cmCPackLogger(cmCPackLog::LOG_DEBUG, "Packagefile " << name << std::endl);
- if (cmHasSuffix(name, broken_suffix_10)) {
- name.replace(name.size() - broken_suffix_10.size(), std::string::npos,
- FreeBSDPackageSuffix_10);
- break;
- }
if (cmHasSuffix(name, broken_suffix_17)) {
name.replace(name.size() - broken_suffix_17.size(), std::string::npos,
FreeBSDPackageSuffix_17);
break;
}
}
- // If the name uses a *new* style name, which doesn't exist, but there
- // is an *old* style name, then use that instead. This indicates we used
- // an older libpkg, which still creates .txz instead of .pkg files.
- for (std::string& name : packageFileNames) {
- if (cmHasSuffix(name, FreeBSDPackageSuffix_17) &&
- !cmSystemTools::FileExists(name)) {
- const std::string badSuffix(FreeBSDPackageSuffix_17);
- const std::string goodSuffix(FreeBSDPackageSuffix_10);
- std::string repairedName(name);
- repairedName.replace(repairedName.size() - badSuffix.size(),
- std::string::npos, goodSuffix);
- if (cmSystemTools::FileExists(repairedName)) {
- name = repairedName;
- cmCPackLogger(cmCPackLog::LOG_DEBUG,
- "Repaired packagefile " << name << std::endl);
- }
+
+ const std::string packageFileName =
+ var_lookup("CPACK_PACKAGE_FILE_NAME") + FreeBSDPackageSuffix_17;
+ if (packageFileNames.size() == 1 && !packageFileName.empty() &&
+ packageFileNames[0] != packageFileName) {
+ // Since libpkg always writes <name>-<version>.<suffix>,
+ // if there is a CPACK_PACKAGE_FILE_NAME set, we need to
+ // rename, and then re-set the name.
+ const std::string sourceFile = packageFileNames[0];
+ const std::string packageSubDirectory =
+ cmSystemTools::GetParentDirectory(sourceFile);
+ const std::string targetFileName =
+ packageSubDirectory + '/' + packageFileName;
+ if (cmSystemTools::RenameFile(sourceFile, targetFileName)) {
+ this->packageFileNames.clear();
+ this->packageFileNames.emplace_back(targetFileName);
}
}
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index 221f7dd..631bfd9 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -1,6 +1,7 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#include <algorithm>
#include <cstddef>
#include <functional>
#include <iostream>
@@ -11,10 +12,12 @@
#include <utility>
#include <vector>
+#include <cm/optional>
#include <cmext/algorithm>
#include "cmsys/Encoding.hxx"
+#include "cmCMakePresetsGraph.h"
#include "cmCPackGenerator.h"
#include "cmCPackGeneratorFactory.h"
#include "cmCPackLog.h"
@@ -50,7 +53,7 @@ const char* cmDocumentationOptions[][2] = {
{ "-C <Configuration>", "Specify the project configuration" },
{ "-D <var>=<value>", "Set a CPack variable." },
{ "--config <configFile>", "Specify the config file." },
- { "--verbose,-V", "Enable verbose output" },
+ { "-V,--verbose", "Enable verbose output" },
{ "--trace", "Put underlying cmake scripts in trace mode." },
{ "--trace-expand", "Put underlying cmake scripts in expanded trace mode." },
{ "--debug", "Enable debug output (for CPack developers)" },
@@ -58,6 +61,8 @@ const char* cmDocumentationOptions[][2] = {
{ "-R <packageVersion>", "Override/define CPACK_PACKAGE_VERSION" },
{ "-B <packageDirectory>", "Override/define CPACK_PACKAGE_DIRECTORY" },
{ "--vendor <vendorName>", "Override/define CPACK_PACKAGE_VENDOR" },
+ { "--preset", "Read arguments from a package preset" },
+ { "--list-presets", "List available package presets" },
{ nullptr, nullptr }
};
@@ -116,6 +121,9 @@ int main(int argc, char const* const* argv)
std::string cpackProjectVendor;
std::string cpackConfigFile;
+ std::string preset;
+ bool listPresets = false;
+
std::map<std::string, std::string> definitions;
auto const verboseLambda = [&log](const std::string&, cmake*,
@@ -182,6 +190,10 @@ int main(int argc, char const* const* argv)
CommandArgument::setToValue(cpackProjectPatch) },
CommandArgument{ "--vendor", CommandArgument::Values::One,
CommandArgument::setToValue(cpackProjectVendor) },
+ CommandArgument{ "--preset", CommandArgument::Values::One,
+ CommandArgument::setToValue(preset) },
+ CommandArgument{ "--list-presets", CommandArgument::Values::Zero,
+ CommandArgument::setToTrue(listPresets) },
CommandArgument{
"-D", CommandArgument::Values::One,
[&log, &definitions](const std::string& arg, cmake*,
@@ -228,6 +240,160 @@ int main(int argc, char const* const* argv)
}
}
+ cmCPackGeneratorFactory generators;
+ generators.SetLogger(&log);
+
+ // Set up presets
+ if (!preset.empty() || listPresets) {
+ const auto workingDirectory = cmSystemTools::GetCurrentWorkingDirectory();
+
+ auto const presetGeneratorsPresent =
+ [&generators](const cmCMakePresetsGraph::PackagePreset& p) {
+ return std::all_of(p.Generators.begin(), p.Generators.end(),
+ [&generators](const std::string& gen) {
+ return generators.GetGeneratorsList().count(
+ gen) != 0;
+ });
+ };
+
+ cmCMakePresetsGraph presetsGraph;
+ auto result = presetsGraph.ReadProjectPresets(workingDirectory);
+ if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Could not read presets from "
+ << workingDirectory << ": "
+ << cmCMakePresetsGraph::ResultToString(result)
+ << std::endl);
+ return 1;
+ }
+
+ if (listPresets) {
+ presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
+ return 0;
+ }
+
+ auto presetPair = presetsGraph.PackagePresets.find(preset);
+ if (presetPair == presetsGraph.PackagePresets.end()) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "No such package preset in " << workingDirectory << ": \""
+ << preset << '"' << std::endl);
+ presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
+ return 1;
+ }
+
+ if (presetPair->second.Unexpanded.Hidden) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Cannot use hidden package preset in "
+ << workingDirectory << ": \"" << preset << '"'
+ << std::endl);
+ presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
+ return 1;
+ }
+
+ auto const& expandedPreset = presetPair->second.Expanded;
+ if (!expandedPreset) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Could not evaluate package preset \""
+ << preset << "\": Invalid macro expansion" << std::endl);
+ presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
+ return 1;
+ }
+
+ if (!expandedPreset->ConditionResult) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Cannot use disabled package preset in "
+ << workingDirectory << ": \"" << preset << '"'
+ << std::endl);
+ presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
+ return 1;
+ }
+
+ if (!presetGeneratorsPresent(presetPair->second.Unexpanded)) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR, "Cannot use preset");
+ presetsGraph.PrintPackagePresetList(presetGeneratorsPresent);
+ return 1;
+ }
+
+ auto configurePresetPair =
+ presetsGraph.ConfigurePresets.find(expandedPreset->ConfigurePreset);
+ if (configurePresetPair == presetsGraph.ConfigurePresets.end()) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "No such configure preset in "
+ << workingDirectory << ": \""
+ << expandedPreset->ConfigurePreset << '"' << std::endl);
+ presetsGraph.PrintConfigurePresetList();
+ return 1;
+ }
+
+ if (configurePresetPair->second.Unexpanded.Hidden) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Cannot use hidden configure preset in "
+ << workingDirectory << ": \""
+ << expandedPreset->ConfigurePreset << '"' << std::endl);
+ presetsGraph.PrintConfigurePresetList();
+ return 1;
+ }
+
+ auto const& expandedConfigurePreset = configurePresetPair->second.Expanded;
+ if (!expandedConfigurePreset) {
+ cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
+ "Could not evaluate configure preset \""
+ << expandedPreset->ConfigurePreset
+ << "\": Invalid macro expansion" << std::endl);
+ return 1;
+ }
+
+ cmSystemTools::ChangeDirectory(expandedConfigurePreset->BinaryDir);
+
+ auto presetEnvironment = expandedPreset->Environment;
+ for (auto const& var : presetEnvironment) {
+ if (var.second) {
+ cmSystemTools::PutEnv(cmStrCat(var.first, '=', *var.second));
+ }
+ }
+
+ if (!expandedPreset->ConfigFile.empty() && cpackConfigFile.empty()) {
+ cpackConfigFile = expandedPreset->ConfigFile;
+ }
+
+ if (!expandedPreset->Generators.empty() && generator.empty()) {
+ generator = cmJoin(expandedPreset->Generators, ";");
+ }
+
+ if (!expandedPreset->Configurations.empty() && cpackBuildConfig.empty()) {
+ cpackBuildConfig = cmJoin(expandedPreset->Configurations, ";");
+ }
+
+ definitions.insert(expandedPreset->Variables.begin(),
+ expandedPreset->Variables.end());
+
+ if (expandedPreset->DebugOutput == true) {
+ debugLambda("", &cminst, &globalMF);
+ }
+
+ if (expandedPreset->VerboseOutput == true) {
+ verboseLambda("", &cminst, &globalMF);
+ }
+
+ if (!expandedPreset->PackageName.empty() && cpackProjectName.empty()) {
+ cpackProjectName = expandedPreset->PackageName;
+ }
+
+ if (!expandedPreset->PackageVersion.empty() &&
+ cpackProjectVersion.empty()) {
+ cpackProjectVersion = expandedPreset->PackageVersion;
+ }
+
+ if (!expandedPreset->PackageDirectory.empty() &&
+ cpackProjectDirectory.empty()) {
+ cpackProjectDirectory = expandedPreset->PackageDirectory;
+ }
+
+ if (!expandedPreset->VendorName.empty() && cpackProjectVendor.empty()) {
+ cpackProjectVendor = expandedPreset->VendorName;
+ }
+ }
+
cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
"Read CPack config file: " << cpackConfigFile << std::endl);
@@ -238,9 +404,6 @@ int main(int argc, char const* const* argv)
cpackConfigFileSpecified = false;
}
- cmCPackGeneratorFactory generators;
- generators.SetLogger(&log);
-
cmDocumentation doc;
doc.addCPackStandardDocSections();
/* Were we invoked to display doc or to do some work ?
diff --git a/Source/CTest/cmCTestCoverageCommand.cxx b/Source/CTest/cmCTestCoverageCommand.cxx
index 7432d08..97b0a89 100644
--- a/Source/CTest/cmCTestCoverageCommand.cxx
+++ b/Source/CTest/cmCTestCoverageCommand.cxx
@@ -4,7 +4,6 @@
#include <set>
-#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmCTest.h"
@@ -18,13 +17,6 @@ void cmCTestCoverageCommand::BindArguments()
this->Bind("LABELS"_s, this->Labels);
}
-void cmCTestCoverageCommand::CheckArguments(
- std::vector<std::string> const& keywords)
-{
- this->LabelsMentioned =
- !this->Labels.empty() || cm::contains(keywords, "LABELS");
-}
-
cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
{
this->CTest->SetCTestConfigurationFromCMakeVariable(
@@ -36,9 +28,9 @@ cmCTestGenericHandler* cmCTestCoverageCommand::InitializeHandler()
handler->Initialize();
// If a LABELS option was given, select only files with the labels.
- if (this->LabelsMentioned) {
+ if (this->Labels) {
handler->SetLabelFilter(
- std::set<std::string>(this->Labels.begin(), this->Labels.end()));
+ std::set<std::string>(this->Labels->begin(), this->Labels->end()));
}
handler->SetQuiet(this->Quiet);
diff --git a/Source/CTest/cmCTestCoverageCommand.h b/Source/CTest/cmCTestCoverageCommand.h
index 9344852..55c68b2 100644
--- a/Source/CTest/cmCTestCoverageCommand.h
+++ b/Source/CTest/cmCTestCoverageCommand.h
@@ -9,7 +9,9 @@
#include <vector>
#include <cm/memory>
+#include <cm/optional>
+#include "cmArgumentParserTypes.h" // IWYU pragma: keep
#include "cmCTestHandlerCommand.h"
#include "cmCommand.h"
@@ -41,9 +43,7 @@ public:
protected:
void BindArguments() override;
- void CheckArguments(std::vector<std::string> const& keywords) override;
cmCTestGenericHandler* InitializeHandler() override;
- bool LabelsMentioned;
- std::vector<std::string> Labels;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Labels;
};
diff --git a/Source/CTest/cmCTestHandlerCommand.cxx b/Source/CTest/cmCTestHandlerCommand.cxx
index 5494d20..be952cd 100644
--- a/Source/CTest/cmCTestHandlerCommand.cxx
+++ b/Source/CTest/cmCTestHandlerCommand.cxx
@@ -7,6 +7,7 @@
#include <cstring>
#include <sstream>
+#include <cm/string_view>
#include <cmext/string_view>
#include "cmCTest.h"
@@ -81,15 +82,13 @@ bool cmCTestHandlerCommand::InitialPass(std::vector<std::string> const& args,
// Process input arguments.
std::vector<std::string> unparsedArguments;
- std::vector<std::string> keywordsMissingValue;
- std::vector<std::string> parsedKeywords;
- this->Parse(args, &unparsedArguments, &keywordsMissingValue,
- &parsedKeywords);
- this->CheckArguments(keywordsMissingValue);
-
- std::sort(parsedKeywords.begin(), parsedKeywords.end());
- auto it = std::adjacent_find(parsedKeywords.begin(), parsedKeywords.end());
- if (it != parsedKeywords.end()) {
+ this->Parse(args, &unparsedArguments);
+ this->CheckArguments();
+
+ std::sort(this->ParsedKeywords.begin(), this->ParsedKeywords.end());
+ auto it = std::adjacent_find(this->ParsedKeywords.begin(),
+ this->ParsedKeywords.end());
+ if (it != this->ParsedKeywords.end()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat("Called with more than one value for ", *it));
@@ -233,6 +232,7 @@ void cmCTestHandlerCommand::ProcessAdditionalValues(cmCTestGenericHandler*)
void cmCTestHandlerCommand::BindArguments()
{
+ this->BindParsedKeywords(this->ParsedKeywords);
this->Bind("APPEND"_s, this->Append);
this->Bind("QUIET"_s, this->Quiet);
this->Bind("RETURN_VALUE"_s, this->ReturnValue);
@@ -242,6 +242,6 @@ void cmCTestHandlerCommand::BindArguments()
this->Bind("SUBMIT_INDEX"_s, this->SubmitIndex);
}
-void cmCTestHandlerCommand::CheckArguments(std::vector<std::string> const&)
+void cmCTestHandlerCommand::CheckArguments()
{
}
diff --git a/Source/CTest/cmCTestHandlerCommand.h b/Source/CTest/cmCTestHandlerCommand.h
index 756952d..ed6d9af 100644
--- a/Source/CTest/cmCTestHandlerCommand.h
+++ b/Source/CTest/cmCTestHandlerCommand.h
@@ -7,6 +7,8 @@
#include <string>
#include <vector>
+#include <cm/string_view>
+
#include "cmArgumentParser.h"
#include "cmCTestCommand.h"
@@ -42,8 +44,9 @@ protected:
// Command argument handling.
virtual void BindArguments();
- virtual void CheckArguments(std::vector<std::string> const& keywords);
+ virtual void CheckArguments();
+ std::vector<cm::string_view> ParsedKeywords;
bool Append = false;
bool Quiet = false;
std::string CaptureCMakeError;
diff --git a/Source/CTest/cmCTestRunTest.cxx b/Source/CTest/cmCTestRunTest.cxx
index 2a2cb1c..5efe69f 100644
--- a/Source/CTest/cmCTestRunTest.cxx
+++ b/Source/CTest/cmCTestRunTest.cxx
@@ -8,16 +8,12 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
-#include <functional>
#include <iomanip>
#include <ratio>
#include <sstream>
#include <utility>
#include <cm/memory>
-#include <cm/optional>
-#include <cm/string_view>
-#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
@@ -787,149 +783,31 @@ bool cmCTestRunTest::ForkProcess(
this->TestProcess->SetTimeout(timeout);
-#ifndef CMAKE_BOOTSTRAP
cmSystemTools::SaveRestoreEnvironment sre;
-#endif
-
std::ostringstream envMeasurement;
+
+ // We split processing ENVIRONMENT and ENVIRONMENT_MODIFICATION into two
+ // phases to ensure that MYVAR=reset: in the latter phase resets to the
+ // former phase's settings, rather than to the original environment.
if (environment && !environment->empty()) {
- // Environment modification works on the assumption that the environment is
- // actually modified here. If another strategy is used, there will need to
- // be updates below in `apply_diff`.
- cmSystemTools::AppendEnv(*environment);
- for (auto const& var : *environment) {
- envMeasurement << var << std::endl;
- }
+ cmSystemTools::EnvDiff diff;
+ diff.AppendEnv(*environment);
+ diff.ApplyToCurrentEnv(&envMeasurement);
}
if (environment_modification && !environment_modification->empty()) {
- std::map<std::string, cm::optional<std::string>> env_application;
-
-#ifdef _WIN32
- char path_sep = ';';
-#else
- char path_sep = ':';
-#endif
-
- auto apply_diff =
- [&env_application](const std::string& name,
- std::function<void(std::string&)> const& apply) {
- cm::optional<std::string> old_value = env_application[name];
- std::string output;
- if (old_value) {
- output = *old_value;
- } else {
- // This only works because the environment is actually modified above
- // (`AppendEnv`). If CTest ever just creates an environment block
- // directly, that block will need to be queried for the subprocess'
- // value instead.
- const char* curval = cmSystemTools::GetEnv(name);
- if (curval) {
- output = curval;
- }
- }
- apply(output);
- env_application[name] = output;
- };
-
- bool err_occurred = false;
+ cmSystemTools::EnvDiff diff;
+ bool env_ok = true;
for (auto const& envmod : *environment_modification) {
- // Split on `=`
- auto const eq_loc = envmod.find_first_of('=');
- if (eq_loc == std::string::npos) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Error: Missing `=` after the variable name in: "
- << envmod << std::endl);
- err_occurred = true;
- continue;
- }
- auto const name = envmod.substr(0, eq_loc);
-
- // Split value on `:`
- auto const op_value_start = eq_loc + 1;
- auto const colon_loc = envmod.find_first_of(':', op_value_start);
- if (colon_loc == std::string::npos) {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Error: Missing `:` after the operation in: " << envmod
- << std::endl);
- err_occurred = true;
- continue;
- }
- auto const op =
- envmod.substr(op_value_start, colon_loc - op_value_start);
-
- auto const value_start = colon_loc + 1;
- auto const value = envmod.substr(value_start);
-
- // Determine what to do with the operation.
- if (op == "reset"_s) {
- auto entry = env_application.find(name);
- if (entry != env_application.end()) {
- env_application.erase(entry);
- }
- } else if (op == "set"_s) {
- env_application[name] = value;
- } else if (op == "unset"_s) {
- env_application[name] = {};
- } else if (op == "string_append"_s) {
- apply_diff(name, [&value](std::string& output) { output += value; });
- } else if (op == "string_prepend"_s) {
- apply_diff(name,
- [&value](std::string& output) { output.insert(0, value); });
- } else if (op == "path_list_append"_s) {
- apply_diff(name, [&value, path_sep](std::string& output) {
- if (!output.empty()) {
- output += path_sep;
- }
- output += value;
- });
- } else if (op == "path_list_prepend"_s) {
- apply_diff(name, [&value, path_sep](std::string& output) {
- if (!output.empty()) {
- output.insert(output.begin(), path_sep);
- }
- output.insert(0, value);
- });
- } else if (op == "cmake_list_append"_s) {
- apply_diff(name, [&value](std::string& output) {
- if (!output.empty()) {
- output += ';';
- }
- output += value;
- });
- } else if (op == "cmake_list_prepend"_s) {
- apply_diff(name, [&value](std::string& output) {
- if (!output.empty()) {
- output.insert(output.begin(), ';');
- }
- output.insert(0, value);
- });
- } else {
- cmCTestLog(this->CTest, ERROR_MESSAGE,
- "Error: Unrecognized environment manipulation argument: "
- << op << std::endl);
- err_occurred = true;
- continue;
- }
+ env_ok &= diff.ParseOperation(envmod);
}
- if (err_occurred) {
+ if (!env_ok) {
return false;
}
- for (auto const& env_apply : env_application) {
- if (env_apply.second) {
- auto const env_update =
- cmStrCat(env_apply.first, '=', *env_apply.second);
- cmSystemTools::PutEnv(env_update);
- envMeasurement << env_update << std::endl;
- } else {
- cmSystemTools::UnsetEnv(env_apply.first.c_str());
- // Signify that this variable is being actively unset
- envMeasurement << "#" << env_apply.first << "=" << std::endl;
- }
- }
+ diff.ApplyToCurrentEnv(&envMeasurement);
}
if (this->UseAllocatedResources) {
diff --git a/Source/CTest/cmCTestSubmitCommand.cxx b/Source/CTest/cmCTestSubmitCommand.cxx
index a2dc615..a1933cc 100644
--- a/Source/CTest/cmCTestSubmitCommand.cxx
+++ b/Source/CTest/cmCTestSubmitCommand.cxx
@@ -8,7 +8,6 @@
#include <cm/memory>
#include <cm/vector>
-#include <cmext/algorithm>
#include <cmext/string_view>
#include "cmCTest.h"
@@ -87,7 +86,7 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
// If FILES are given, but not PARTS, only the FILES are submitted
// and *no* PARTS are submitted.
// (This is why we select the empty "noParts" set in the
- // FilesMentioned block below...)
+ // if(this->Files) block below...)
//
// If PARTS are given, only the selected PARTS are submitted.
//
@@ -96,7 +95,7 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
// If given explicit FILES to submit, pass them to the handler.
//
- if (this->FilesMentioned) {
+ if (this->Files) {
// Intentionally select *no* PARTS. (Pass an empty set.) If PARTS
// were also explicitly mentioned, they will be selected below...
// But FILES with no PARTS mentioned should just submit the FILES
@@ -104,14 +103,14 @@ cmCTestGenericHandler* cmCTestSubmitCommand::InitializeHandler()
//
handler->SelectParts(std::set<cmCTest::Part>());
handler->SelectFiles(
- std::set<std::string>(this->Files.begin(), this->Files.end()));
+ std::set<std::string>(this->Files->begin(), this->Files->end()));
}
// If a PARTS option was given, select only the named parts for submission.
//
- if (this->PartsMentioned) {
+ if (this->Parts) {
auto parts =
- cmMakeRange(this->Parts).transform([this](std::string const& arg) {
+ cmMakeRange(*(this->Parts)).transform([this](std::string const& arg) {
return this->CTest->GetPartFromName(arg);
});
handler->SelectParts(std::set<cmCTest::Part>(parts.begin(), parts.end()));
@@ -172,33 +171,31 @@ void cmCTestSubmitCommand::BindArguments()
this->cmCTestHandlerCommand::BindArguments();
}
-void cmCTestSubmitCommand::CheckArguments(
- std::vector<std::string> const& keywords)
+void cmCTestSubmitCommand::CheckArguments()
{
- this->PartsMentioned =
- !this->Parts.empty() || cm::contains(keywords, "PARTS");
- this->FilesMentioned =
- !this->Files.empty() || cm::contains(keywords, "FILES");
-
- cm::erase_if(this->Parts, [this](std::string const& arg) -> bool {
- cmCTest::Part p = this->CTest->GetPartFromName(arg);
- if (p == cmCTest::PartCount) {
- std::ostringstream e;
- e << "Part name \"" << arg << "\" is invalid.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return true;
- }
- return false;
- });
-
- cm::erase_if(this->Files, [this](std::string const& arg) -> bool {
- if (!cmSystemTools::FileExists(arg)) {
- std::ostringstream e;
- e << "File \"" << arg << "\" does not exist. Cannot submit "
- << "a non-existent file.";
- this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return true;
- }
- return false;
- });
+ if (this->Parts) {
+ cm::erase_if(*(this->Parts), [this](std::string const& arg) -> bool {
+ cmCTest::Part p = this->CTest->GetPartFromName(arg);
+ if (p == cmCTest::PartCount) {
+ std::ostringstream e;
+ e << "Part name \"" << arg << "\" is invalid.";
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return true;
+ }
+ return false;
+ });
+ }
+
+ if (this->Files) {
+ cm::erase_if(*(this->Files), [this](std::string const& arg) -> bool {
+ if (!cmSystemTools::FileExists(arg)) {
+ std::ostringstream e;
+ e << "File \"" << arg << "\" does not exist. Cannot submit "
+ << "a non-existent file.";
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return true;
+ }
+ return false;
+ });
+ }
}
diff --git a/Source/CTest/cmCTestSubmitCommand.h b/Source/CTest/cmCTestSubmitCommand.h
index c5d11df..b67f182 100644
--- a/Source/CTest/cmCTestSubmitCommand.h
+++ b/Source/CTest/cmCTestSubmitCommand.h
@@ -8,6 +8,9 @@
#include <string>
#include <vector>
+#include <cm/optional>
+
+#include "cmArgumentParserTypes.h"
#include "cmCTestHandlerCommand.h"
class cmCommand;
@@ -35,13 +38,11 @@ public:
protected:
void BindArguments() override;
- void CheckArguments(std::vector<std::string> const& keywords) override;
+ void CheckArguments() override;
cmCTestGenericHandler* InitializeHandler() override;
bool CDashUpload = false;
- bool FilesMentioned = false;
bool InternalTest = false;
- bool PartsMentioned = false;
std::string BuildID;
std::string CDashUploadFile;
@@ -50,7 +51,7 @@ protected:
std::string RetryDelay;
std::string SubmitURL;
- std::vector<std::string> Files;
- std::vector<std::string> HttpHeaders;
- std::vector<std::string> Parts;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Files;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> HttpHeaders;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Parts;
};
diff --git a/Source/CTest/cmCTestUploadCommand.cxx b/Source/CTest/cmCTestUploadCommand.cxx
index f86ee0d..2ed671c 100644
--- a/Source/CTest/cmCTestUploadCommand.cxx
+++ b/Source/CTest/cmCTestUploadCommand.cxx
@@ -21,7 +21,7 @@ void cmCTestUploadCommand::BindArguments()
this->Bind("CAPTURE_CMAKE_ERROR"_s, this->CaptureCMakeError);
}
-void cmCTestUploadCommand::CheckArguments(std::vector<std::string> const&)
+void cmCTestUploadCommand::CheckArguments()
{
cm::erase_if(this->Files, [this](std::string const& arg) -> bool {
if (!cmSystemTools::FileExists(arg)) {
diff --git a/Source/CTest/cmCTestUploadCommand.h b/Source/CTest/cmCTestUploadCommand.h
index fe155f6..a9d1dd2 100644
--- a/Source/CTest/cmCTestUploadCommand.h
+++ b/Source/CTest/cmCTestUploadCommand.h
@@ -10,6 +10,7 @@
#include <cm/memory>
+#include "cmArgumentParserTypes.h"
#include "cmCTestHandlerCommand.h"
#include "cmCommand.h"
@@ -42,8 +43,8 @@ public:
protected:
void BindArguments() override;
- void CheckArguments(std::vector<std::string> const&) override;
+ void CheckArguments() override;
cmCTestGenericHandler* InitializeHandler() override;
- std::vector<std::string> Files;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Files;
};
diff --git a/Source/CursesDialog/cmCursesLongMessageForm.cxx b/Source/CursesDialog/cmCursesLongMessageForm.cxx
index b14a751..6e6f0d6 100644
--- a/Source/CursesDialog/cmCursesLongMessageForm.cxx
+++ b/Source/CursesDialog/cmCursesLongMessageForm.cxx
@@ -85,7 +85,7 @@ void cmCursesLongMessageForm::UpdateStatusBar()
for (size_t i = 0; i < sideSpace; i++) {
version[i] = ' ';
}
- sprintf(version + sideSpace, "%s", vertmp);
+ snprintf(version + sideSpace, sizeof(version) - sideSpace, "%s", vertmp);
version[width] = '\0';
char fmt_s[] = "%s";
diff --git a/Source/CursesDialog/form/.gitattributes b/Source/CursesDialog/form/.gitattributes
index 12ede74..6dfa627 100644
--- a/Source/CursesDialog/form/.gitattributes
+++ b/Source/CursesDialog/form/.gitattributes
@@ -1 +1,2 @@
+* -whitespace
* -format.clang-format-6.0
diff --git a/Source/CursesDialog/form/fty_int.c b/Source/CursesDialog/form/fty_int.c
index 7107fcc..7aeb4b8 100644
--- a/Source/CursesDialog/form/fty_int.c
+++ b/Source/CursesDialog/form/fty_int.c
@@ -117,7 +117,7 @@ static bool Check_Integer_Field(FIELD * field, const void * argp)
{
if (val<low || val>high) return FALSE;
}
- sprintf(buf,"%.*ld",(prec>0?prec:0),val);
+ snprintf(buf,sizeof(buf),"%.*ld",(prec>0?prec:0),val);
set_field_buffer(field,0,buf);
return TRUE;
}
diff --git a/Source/CursesDialog/form/fty_num.c b/Source/CursesDialog/form/fty_num.c
index 7809599..4109b6f 100644
--- a/Source/CursesDialog/form/fty_num.c
+++ b/Source/CursesDialog/form/fty_num.c
@@ -140,7 +140,7 @@ static bool Check_Numeric_Field(FIELD * field, const void * argp)
{
if (val<low || val>high) return FALSE;
}
- sprintf(buf,"%.*f",(prec>0?prec:0),val);
+ snprintf(buf,sizeof(buf),"%.*f",(prec>0?prec:0),val);
set_field_buffer(field,0,buf);
return TRUE;
}
diff --git a/Source/LexerParser/cmFortranLexer.cxx b/Source/LexerParser/cmFortranLexer.cxx
index c3d0000..5703de1 100644
--- a/Source/LexerParser/cmFortranLexer.cxx
+++ b/Source/LexerParser/cmFortranLexer.cxx
@@ -557,31 +557,32 @@ struct yy_trans_info
flex_int32_t yy_verify;
flex_int32_t yy_nxt;
};
-static const flex_int16_t yy_accept[210] =
+static const flex_int16_t yy_accept[216] =
{ 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55, 49, 51, 50, 53, 1, 49, 33, 2, 47,
48, 35, 37, 50, 39, 49, 46, 46, 46, 46,
- 46, 46, 49, 46, 51, 49, 50, 49, 46, 9,
- 8, 9, 4, 3, 49, 0, 10, 0, 0, 0,
- 0, 0, 33, 33, 34, 36, 39, 49, 46, 46,
- 46, 46, 46, 46, 0, 52, 46, 0, 0, 0,
- 12, 0, 0, 0, 0, 0, 0, 49, 0, 11,
- 46, 0, 0, 5, 0, 0, 0, 0, 29, 0,
- 33, 33, 33, 33, 0, 0, 40, 46, 46, 46,
-
- 46, 45, 12, 12, 0, 0, 0, 23, 0, 0,
- 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 46, 46, 46, 46, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 30, 31, 0, 0, 0, 0, 0, 46, 46,
- 46, 46, 0, 24, 25, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 20, 32, 27, 0, 0, 0,
- 46, 46, 43, 46, 0, 26, 21, 0, 0, 0,
- 19, 0, 0, 18, 28, 0, 0, 41, 46, 46,
- 17, 22, 0, 7, 38, 7, 15, 0, 46, 46,
-
- 14, 16, 42, 44, 0, 0, 0, 13, 0
+ 46, 46, 49, 46, 51, 49, 50, 51, 49, 46,
+ 9, 8, 9, 9, 4, 3, 49, 0, 10, 0,
+ 0, 0, 0, 0, 33, 33, 34, 36, 39, 49,
+ 46, 46, 46, 46, 46, 46, 0, 52, 0, 46,
+ 0, 0, 0, 12, 0, 0, 0, 0, 0, 0,
+ 0, 49, 0, 11, 46, 0, 0, 0, 5, 0,
+ 0, 0, 0, 0, 29, 0, 33, 33, 33, 33,
+
+ 0, 0, 40, 46, 46, 46, 46, 45, 12, 12,
+ 0, 0, 0, 23, 0, 0, 0, 0, 0, 0,
+ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 46, 46, 46, 46, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 30, 31, 0,
+ 0, 0, 0, 0, 46, 46, 46, 46, 0, 24,
+ 25, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 20, 32, 27, 0, 0, 0, 46, 46, 43, 46,
+ 0, 26, 21, 0, 0, 0, 19, 0, 0, 18,
+ 28, 0, 0, 41, 46, 46, 17, 22, 0, 7,
+
+ 38, 7, 15, 0, 46, 46, 14, 16, 42, 44,
+ 0, 0, 0, 13, 0
} ;
static const YY_CHAR yy_ec[256] =
@@ -618,189 +619,197 @@ static const YY_CHAR yy_ec[256] =
static const YY_CHAR yy_meta[50] =
{ 0,
- 1, 2, 2, 3, 4, 3, 3, 1, 1, 3,
- 3, 3, 3, 1, 3, 5, 3, 3, 1, 3,
+ 1, 2, 2, 2, 3, 4, 4, 1, 1, 4,
+ 4, 4, 4, 1, 4, 5, 4, 4, 1, 4,
6, 1, 7, 7, 7, 7, 7, 7, 7, 7,
7, 7, 7, 7, 7, 7, 7, 7, 1, 5,
7, 7, 7, 7, 7, 7, 7, 7, 7
} ;
-static const flex_int16_t yy_base[219] =
+static const flex_int16_t yy_base[225] =
{ 0,
- 0, 48, 0, 49, 464, 56, 52, 57, 62, 68,
- 466, 0, 468, 468, 462, 468, 74, 81, 468, 468,
- 468, 468, 447, 468, 442, 440, 0, 19, 41, 427,
- 47, 41, 90, 119, 97, 158, 455, 207, 247, 468,
- 454, 101, 468, 468, 0, 455, 468, 105, 430, 423,
- 62, 67, 119, 151, 468, 468, 468, 121, 0, 90,
- 93, 110, 431, 112, 142, 468, 0, 160, 295, 0,
- 162, 411, 123, 102, 408, 405, 446, 344, 447, 468,
- 0, 444, 170, 174, 420, 421, 132, 404, 95, 404,
- 180, 186, 192, 228, 297, 397, 0, 168, 144, 52,
-
- 411, 0, 204, 217, 397, 179, 390, 170, 389, 378,
- 364, 390, 389, 230, 468, 363, 355, 337, 337, 334,
- 335, 335, 330, 334, 187, 339, 267, 339, 327, 327,
- 327, 324, 325, 325, 318, 319, 318, 354, 352, 323,
- 327, 468, 468, 310, 307, 305, 297, 297, 275, 275,
- 277, 279, 287, 468, 468, 286, 283, 273, 196, 307,
- 200, 238, 234, 210, 468, 468, 468, 174, 171, 162,
- 279, 182, 0, 269, 150, 468, 468, 137, 109, 323,
- 468, 239, 0, 468, 468, 72, 71, 0, 283, 283,
- 468, 468, 51, 468, 468, 468, 468, 37, 283, 288,
-
- 330, 468, 0, 0, 331, 0, 52, 468, 468, 384,
- 391, 397, 400, 407, 414, 421, 428, 435
+ 0, 48, 0, 49, 55, 58, 64, 66, 75, 83,
+ 491, 0, 492, 492, 487, 492, 86, 92, 492, 492,
+ 492, 492, 472, 492, 467, 465, 0, 56, 59, 452,
+ 66, 16, 105, 131, 109, 170, 480, 481, 219, 259,
+ 492, 478, 479, 116, 492, 492, 0, 478, 492, 111,
+ 453, 446, 34, 78, 155, 174, 492, 492, 492, 121,
+ 0, 29, 105, 101, 454, 101, 131, 492, 474, 0,
+ 180, 307, 0, 146, 433, 117, 94, 430, 427, 468,
+ 467, 356, 468, 492, 0, 465, 464, 187, 191, 465,
+ 439, 440, 149, 423, 126, 423, 200, 240, 311, 322,
+
+ 206, 416, 0, 152, 180, 176, 430, 0, 216, 224,
+ 417, 186, 418, 127, 418, 411, 415, 451, 450, 247,
+ 492, 423, 416, 398, 393, 373, 364, 364, 359, 353,
+ 198, 358, 178, 358, 346, 346, 346, 343, 344, 344,
+ 338, 340, 339, 376, 374, 343, 346, 492, 492, 329,
+ 325, 324, 313, 315, 211, 211, 291, 293, 313, 492,
+ 492, 314, 304, 304, 261, 328, 212, 249, 243, 203,
+ 492, 492, 492, 173, 158, 150, 293, 172, 0, 273,
+ 144, 492, 492, 137, 125, 335, 492, 339, 0, 492,
+ 492, 112, 63, 0, 304, 300, 492, 492, 58, 492,
+
+ 492, 492, 492, 30, 311, 312, 361, 492, 0, 0,
+ 366, 0, 44, 492, 492, 396, 403, 409, 412, 419,
+ 426, 433, 440, 447
} ;
-static const flex_int16_t yy_def[219] =
+static const flex_int16_t yy_def[225] =
{ 0,
- 209, 1, 1, 1, 1, 1, 210, 210, 210, 210,
- 209, 211, 209, 209, 212, 209, 211, 209, 209, 209,
- 209, 209, 209, 209, 209, 211, 213, 213, 213, 213,
- 213, 213, 211, 213, 209, 211, 209, 214, 209, 209,
- 209, 209, 209, 209, 211, 212, 209, 209, 209, 209,
- 209, 209, 209, 215, 209, 209, 209, 211, 213, 213,
- 213, 213, 213, 213, 209, 209, 34, 209, 209, 69,
- 211, 209, 209, 209, 209, 209, 209, 214, 214, 209,
- 39, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 215, 215, 215, 215, 209, 209, 213, 213, 213, 213,
-
- 213, 213, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 213, 213, 213, 213, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 213, 213,
- 213, 213, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 213, 213, 213, 213, 209, 209, 209, 209, 209, 209,
- 209, 216, 217, 209, 209, 209, 209, 213, 213, 213,
- 209, 209, 209, 209, 209, 209, 209, 209, 213, 213,
-
- 209, 209, 213, 213, 209, 218, 218, 209, 0, 209,
- 209, 209, 209, 209, 209, 209, 209, 209
+ 215, 1, 1, 1, 1, 1, 216, 216, 216, 216,
+ 215, 217, 215, 215, 218, 215, 217, 215, 215, 215,
+ 215, 215, 215, 215, 215, 217, 219, 219, 219, 219,
+ 219, 219, 217, 219, 215, 217, 215, 215, 220, 215,
+ 215, 215, 215, 215, 215, 215, 217, 218, 215, 215,
+ 215, 215, 215, 215, 215, 221, 215, 215, 215, 217,
+ 219, 219, 219, 219, 219, 219, 215, 215, 215, 34,
+ 215, 215, 72, 217, 215, 215, 215, 215, 215, 215,
+ 215, 220, 220, 215, 40, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 221, 221, 221, 221,
+
+ 215, 215, 219, 219, 219, 219, 219, 219, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 219, 219, 219, 219, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 219, 219, 219, 219, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 219, 219, 219, 219,
+ 215, 215, 215, 215, 215, 215, 215, 222, 223, 215,
+ 215, 215, 215, 219, 219, 219, 215, 215, 215, 215,
+
+ 215, 215, 215, 215, 219, 219, 215, 215, 219, 219,
+ 215, 224, 224, 215, 0, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215
} ;
-static const flex_int16_t yy_nxt[518] =
+static const flex_int16_t yy_nxt[542] =
{ 0,
12, 13, 14, 13, 13, 15, 16, 12, 17, 18,
19, 20, 21, 12, 22, 12, 23, 24, 12, 25,
12, 26, 27, 27, 27, 27, 28, 27, 27, 29,
27, 30, 27, 27, 27, 31, 27, 32, 33, 34,
27, 27, 28, 27, 29, 27, 27, 31, 32, 35,
- 35, 60, 35, 35, 41, 36, 36, 35, 37, 41,
- 35, 42, 43, 36, 41, 60, 42, 43, 44, 38,
- 41, 42, 208, 61, 44, 48, 64, 42, 48, 202,
- 39, 39, 53, 53, 63, 53, 54, 61, 64, 127,
- 55, 65, 66, 201, 65, 63, 39, 39, 68, 49,
-
- 127, 68, 83, 84, 69, 83, 48, 87, 88, 48,
- 89, 50, 198, 90, 197, 97, 51, 98, 52, 45,
- 53, 53, 95, 53, 54, 95, 45, 45, 55, 99,
- 49, 97, 45, 98, 67, 100, 121, 45, 102, 45,
- 45, 122, 50, 65, 66, 108, 65, 51, 109, 52,
- 193, 100, 92, 53, 102, 92, 93, 45, 67, 70,
- 94, 68, 70, 104, 68, 96, 104, 69, 106, 107,
- 126, 83, 84, 71, 83, 114, 118, 71, 114, 119,
- 192, 92, 53, 115, 92, 93, 126, 92, 53, 94,
- 92, 93, 191, 92, 53, 94, 92, 93, 125, 72,
-
- 73, 94, 74, 75, 189, 104, 76, 78, 104, 80,
- 187, 133, 186, 125, 78, 78, 134, 185, 104, 103,
- 78, 104, 78, 130, 149, 78, 131, 78, 78, 92,
- 53, 114, 92, 93, 114, 149, 184, 94, 183, 115,
- 195, 195, 182, 181, 179, 78, 78, 79, 79, 80,
- 79, 79, 79, 79, 79, 79, 79, 79, 79, 79,
- 79, 79, 81, 79, 79, 79, 79, 79, 79, 81,
- 81, 81, 81, 81, 81, 81, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 79, 81, 81, 81, 81,
- 81, 81, 81, 81, 81, 81, 70, 151, 95, 70,
-
- 171, 95, 172, 173, 174, 188, 190, 199, 180, 203,
- 103, 180, 151, 200, 204, 178, 171, 190, 172, 173,
- 174, 188, 103, 199, 180, 203, 177, 180, 200, 176,
- 204, 205, 205, 175, 205, 205, 72, 73, 103, 74,
- 75, 96, 170, 76, 78, 169, 80, 168, 206, 206,
- 167, 78, 78, 166, 165, 164, 163, 78, 162, 78,
- 161, 160, 78, 159, 78, 78, 158, 157, 156, 155,
- 154, 153, 152, 150, 148, 147, 146, 145, 144, 143,
- 142, 141, 78, 78, 40, 40, 40, 40, 40, 40,
- 40, 45, 140, 139, 138, 45, 45, 46, 46, 46,
-
- 46, 46, 46, 46, 59, 137, 59, 79, 79, 79,
- 79, 79, 79, 79, 91, 91, 91, 91, 91, 91,
- 91, 194, 194, 194, 136, 194, 194, 194, 196, 135,
- 196, 132, 196, 196, 196, 207, 207, 207, 207, 207,
- 129, 207, 128, 124, 123, 120, 117, 116, 113, 80,
- 112, 111, 110, 105, 101, 86, 85, 47, 82, 77,
- 62, 58, 57, 56, 47, 209, 37, 11, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
-
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209
+ 35, 66, 35, 35, 103, 36, 36, 37, 38, 35,
+ 37, 38, 35, 66, 214, 36, 42, 43, 42, 43,
+ 103, 39, 208, 44, 45, 44, 45, 42, 43, 93,
+ 94, 46, 40, 40, 44, 42, 43, 50, 62, 46,
+ 50, 63, 44, 55, 55, 55, 55, 56, 40, 40,
+
+ 207, 57, 62, 65, 204, 63, 67, 68, 69, 67,
+ 71, 51, 50, 71, 65, 50, 72, 88, 89, 90,
+ 88, 95, 101, 52, 96, 101, 106, 108, 53, 104,
+ 54, 47, 67, 68, 69, 67, 51, 114, 47, 47,
+ 115, 105, 106, 108, 47, 104, 70, 110, 52, 47,
+ 110, 47, 47, 53, 203, 54, 55, 55, 55, 55,
+ 56, 74, 112, 113, 57, 102, 199, 127, 139, 47,
+ 70, 73, 128, 140, 73, 98, 55, 98, 98, 99,
+ 198, 71, 131, 100, 71, 74, 197, 72, 88, 89,
+ 90, 88, 120, 124, 195, 120, 125, 131, 193, 192,
+
+ 121, 98, 55, 98, 98, 99, 132, 101, 157, 100,
+ 101, 75, 76, 133, 77, 78, 191, 110, 79, 82,
+ 110, 84, 132, 157, 133, 110, 82, 82, 110, 190,
+ 136, 109, 82, 137, 82, 155, 177, 82, 178, 82,
+ 82, 98, 55, 98, 98, 99, 155, 189, 120, 100,
+ 102, 120, 177, 188, 178, 187, 121, 82, 82, 83,
+ 83, 84, 83, 83, 83, 83, 83, 83, 83, 83,
+ 83, 83, 83, 83, 85, 83, 83, 83, 83, 83,
+ 83, 85, 85, 85, 85, 85, 85, 85, 85, 85,
+ 85, 85, 85, 85, 85, 85, 85, 83, 85, 85,
+
+ 85, 85, 85, 85, 85, 85, 85, 85, 73, 185,
+ 196, 73, 98, 55, 98, 98, 99, 179, 180, 194,
+ 100, 196, 109, 98, 55, 98, 98, 99, 205, 186,
+ 206, 100, 186, 179, 180, 194, 186, 209, 210, 186,
+ 201, 201, 201, 109, 205, 206, 184, 183, 75, 76,
+ 109, 77, 78, 209, 210, 79, 82, 182, 84, 181,
+ 176, 175, 211, 82, 82, 211, 174, 211, 173, 82,
+ 211, 82, 172, 171, 82, 170, 82, 82, 169, 212,
+ 168, 167, 166, 165, 212, 164, 163, 162, 161, 160,
+ 159, 158, 156, 154, 82, 82, 41, 41, 41, 41,
+
+ 41, 41, 41, 47, 153, 152, 151, 47, 47, 48,
+ 48, 48, 48, 48, 48, 48, 61, 150, 61, 83,
+ 83, 83, 83, 83, 83, 83, 97, 97, 97, 97,
+ 97, 97, 97, 200, 200, 149, 200, 200, 200, 200,
+ 202, 148, 147, 202, 202, 202, 202, 213, 213, 213,
+ 213, 213, 146, 213, 145, 144, 143, 142, 141, 138,
+ 135, 134, 130, 129, 126, 123, 122, 89, 86, 119,
+ 84, 80, 118, 117, 116, 111, 68, 107, 92, 91,
+ 49, 87, 86, 81, 80, 64, 60, 59, 58, 49,
+ 215, 11, 215, 215, 215, 215, 215, 215, 215, 215,
+
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215
} ;
-static const flex_int16_t yy_chk[518] =
+static const flex_int16_t yy_chk[542] =
{ 0,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2,
- 4, 28, 2, 4, 7, 2, 4, 6, 6, 8,
- 6, 7, 7, 6, 9, 28, 8, 8, 9, 6,
- 10, 9, 207, 29, 10, 17, 32, 10, 17, 198,
- 6, 6, 18, 18, 31, 18, 18, 29, 32, 100,
- 18, 33, 33, 193, 33, 31, 6, 6, 35, 17,
-
- 100, 35, 42, 42, 35, 42, 48, 51, 51, 48,
- 52, 17, 187, 52, 186, 60, 17, 61, 17, 34,
- 53, 53, 58, 53, 53, 58, 34, 34, 53, 61,
- 48, 60, 34, 61, 34, 62, 89, 34, 64, 34,
- 34, 89, 48, 65, 65, 74, 65, 48, 74, 48,
- 179, 62, 54, 54, 64, 54, 54, 34, 34, 36,
- 54, 68, 36, 71, 68, 58, 71, 68, 73, 73,
- 99, 83, 83, 36, 83, 84, 87, 71, 84, 87,
- 178, 91, 91, 84, 91, 91, 99, 92, 92, 91,
- 92, 92, 175, 93, 93, 92, 93, 93, 98, 36,
-
- 36, 93, 36, 36, 172, 103, 36, 38, 103, 38,
- 170, 108, 169, 98, 38, 38, 108, 168, 104, 103,
- 38, 104, 38, 106, 125, 38, 106, 38, 38, 94,
- 94, 114, 94, 94, 114, 125, 164, 94, 163, 114,
- 182, 182, 162, 161, 159, 38, 38, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 39, 39, 39, 39,
- 39, 39, 39, 39, 39, 39, 69, 127, 95, 69,
-
- 149, 95, 150, 151, 152, 171, 174, 189, 160, 199,
- 69, 160, 127, 190, 200, 158, 149, 174, 150, 151,
- 152, 171, 160, 189, 180, 199, 157, 180, 190, 156,
- 200, 201, 205, 153, 201, 205, 69, 69, 180, 69,
- 69, 95, 148, 69, 78, 147, 78, 146, 201, 205,
- 145, 78, 78, 144, 141, 140, 139, 78, 138, 78,
- 137, 136, 78, 135, 78, 78, 134, 133, 132, 131,
- 130, 129, 128, 126, 124, 123, 122, 121, 120, 119,
- 118, 117, 78, 78, 210, 210, 210, 210, 210, 210,
- 210, 211, 116, 113, 112, 211, 211, 212, 212, 212,
-
- 212, 212, 212, 212, 213, 111, 213, 214, 214, 214,
- 214, 214, 214, 214, 215, 215, 215, 215, 215, 215,
- 215, 216, 216, 216, 110, 216, 216, 216, 217, 109,
- 217, 107, 217, 217, 217, 218, 218, 218, 218, 218,
- 105, 218, 101, 96, 90, 88, 86, 85, 82, 79,
- 77, 76, 75, 72, 63, 50, 49, 46, 41, 37,
- 30, 26, 25, 23, 15, 11, 5, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
-
- 209, 209, 209, 209, 209, 209, 209, 209, 209, 209,
- 209, 209, 209, 209, 209, 209, 209
+ 4, 32, 2, 4, 62, 2, 4, 5, 5, 6,
+ 6, 6, 6, 32, 213, 6, 7, 7, 8, 8,
+ 62, 6, 204, 7, 7, 8, 8, 9, 9, 53,
+ 53, 9, 6, 6, 9, 10, 10, 17, 28, 10,
+ 17, 29, 10, 18, 18, 18, 18, 18, 6, 6,
+
+ 199, 18, 28, 31, 193, 29, 33, 33, 33, 33,
+ 35, 17, 50, 35, 31, 50, 35, 44, 44, 44,
+ 44, 54, 60, 17, 54, 60, 64, 66, 17, 63,
+ 17, 34, 67, 67, 67, 67, 50, 77, 34, 34,
+ 77, 63, 64, 66, 34, 63, 34, 74, 50, 34,
+ 74, 34, 34, 50, 192, 50, 55, 55, 55, 55,
+ 55, 74, 76, 76, 55, 60, 185, 95, 114, 34,
+ 34, 36, 95, 114, 36, 56, 56, 56, 56, 56,
+ 184, 71, 104, 56, 71, 36, 181, 71, 88, 88,
+ 88, 88, 89, 93, 178, 89, 93, 104, 176, 175,
+
+ 89, 97, 97, 97, 97, 97, 105, 101, 133, 97,
+ 101, 36, 36, 106, 36, 36, 174, 109, 36, 39,
+ 109, 39, 105, 133, 106, 110, 39, 39, 110, 170,
+ 112, 109, 39, 112, 39, 131, 155, 39, 156, 39,
+ 39, 98, 98, 98, 98, 98, 131, 169, 120, 98,
+ 101, 120, 155, 168, 156, 167, 120, 39, 39, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+
+ 40, 40, 40, 40, 40, 40, 40, 40, 72, 165,
+ 180, 72, 99, 99, 99, 99, 99, 157, 158, 177,
+ 99, 180, 72, 100, 100, 100, 100, 100, 195, 166,
+ 196, 100, 166, 157, 158, 177, 186, 205, 206, 186,
+ 188, 188, 188, 166, 195, 196, 164, 163, 72, 72,
+ 186, 72, 72, 205, 206, 72, 82, 162, 82, 159,
+ 154, 153, 207, 82, 82, 207, 152, 211, 151, 82,
+ 211, 82, 150, 147, 82, 146, 82, 82, 145, 207,
+ 144, 143, 142, 141, 211, 140, 139, 138, 137, 136,
+ 135, 134, 132, 130, 82, 82, 216, 216, 216, 216,
+
+ 216, 216, 216, 217, 129, 128, 127, 217, 217, 218,
+ 218, 218, 218, 218, 218, 218, 219, 126, 219, 220,
+ 220, 220, 220, 220, 220, 220, 221, 221, 221, 221,
+ 221, 221, 221, 222, 222, 125, 222, 222, 222, 222,
+ 223, 124, 123, 223, 223, 223, 223, 224, 224, 224,
+ 224, 224, 122, 224, 119, 118, 117, 116, 115, 113,
+ 111, 107, 102, 96, 94, 92, 91, 90, 87, 86,
+ 83, 81, 80, 79, 78, 75, 69, 65, 52, 51,
+ 48, 43, 42, 38, 37, 30, 26, 25, 23, 15,
+ 11, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215, 215, 215, 215, 215, 215, 215, 215, 215, 215,
+ 215
} ;
/* The intent behind this definition is that it'll catch
@@ -1139,13 +1148,13 @@ yy_match:
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 210 )
+ if ( yy_current_state >= 216 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
++yy_cp;
}
- while ( yy_base[yy_current_state] != 468 );
+ while ( yy_base[yy_current_state] != 492 );
yy_find_action:
yy_act = yy_accept[yy_current_state];
@@ -1733,7 +1742,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 210 )
+ if ( yy_current_state >= 216 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
@@ -1762,11 +1771,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner)
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
{
yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 210 )
+ if ( yy_current_state >= 216 )
yy_c = yy_meta[yy_c];
}
yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c];
- yy_is_jam = (yy_current_state == 209);
+ yy_is_jam = (yy_current_state == 215);
(void)yyg;
return yy_is_jam ? 0 : yy_current_state;
diff --git a/Source/LexerParser/cmFortranLexer.in.l b/Source/LexerParser/cmFortranLexer.in.l
index 05769a1..fac3181 100644
--- a/Source/LexerParser/cmFortranLexer.in.l
+++ b/Source/LexerParser/cmFortranLexer.in.l
@@ -75,10 +75,10 @@ Modify cmFortranLexer.cxx:
return STRING;
}
-<str_dq,str_sq>&[ \t]*\n |
-<str_dq,str_sq>&[ \t]*\n[ \t]*& /* Ignore (continued strings, free fmt) */
+<str_dq,str_sq>&[ \t]*\r?\n |
+<str_dq,str_sq>&[ \t]*\r?\n[ \t]*& /* Ignore (continued strings, free fmt) */
-<fixed_fmt,str_dq,str_sq>\n[ ]{5}[^ \t\n] {
+<fixed_fmt,str_dq,str_sq>\r?\n[ ]{5}[^ \t\r\n] {
if (cmFortranParser_GetOldStartcond(yyextra) == fixed_fmt)
; /* Ignore (cont. strings, fixed fmt) */
else
@@ -132,15 +132,15 @@ $[ \t]*else { return F90PPR_ELSE; }
$[ \t]*endif { return F90PPR_ENDIF; }
/* Line continuations, possible involving comments. */
-&([ \t\n]*|!.*)*
-&([ \t\n]*|!.*)*&
+&([ \t\r\n]*|!.*)*
+&([ \t\r\n]*|!.*)*&
, { return COMMA; }
:: { return DCOLON; }
: { return COLON; }
-<fixed_fmt>\n[ ]{5}[^ ] { return GARBAGE; }
+<fixed_fmt>\r?\n[ ]{5}[^ ] { return GARBAGE; }
=|=> { return ASSIGNMENT_OP; }
@@ -159,13 +159,13 @@ $[ \t]*endif { return F90PPR_ENDIF; }
\( { return LPAREN; }
\) { return RPAREN; }
-[^ \t\n\r:;,!'"a-zA-Z=&()]+ { return GARBAGE; }
+[^ \t\r\n:;,!'"a-zA-Z=&()]+ { return GARBAGE; }
;|\n { return EOSTMT; }
[ \t\r,] /* Ignore */
-\\[ \t]*\n /* Ignore line-endings preceded by \ */
+\\[ \t]*\r?\n /* Ignore line-endings preceded by \ */
. { return *yytext; }
diff --git a/Source/LexerParser/cmFortranParser.cxx b/Source/LexerParser/cmFortranParser.cxx
index b177296..5e5cc0b 100644
--- a/Source/LexerParser/cmFortranParser.cxx
+++ b/Source/LexerParser/cmFortranParser.cxx
@@ -548,7 +548,7 @@ union yyalloc
/* YYFINAL -- State number of the termination state. */
#define YYFINAL 2
/* YYLAST -- Last index in YYTABLE. */
-#define YYLAST 594
+#define YYLAST 432
/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS 41
@@ -557,7 +557,7 @@ union yyalloc
/* YYNRULES -- Number of rules. */
#define YYNRULES 64
/* YYNSTATES -- Number of states. */
-#define YYNSTATES 127
+#define YYNSTATES 121
/* YYMAXUTOK -- Last valid token kind. */
#define YYMAXUTOK 295
@@ -608,15 +608,15 @@ static const yytype_int8 yytranslate[] =
#if YYDEBUG
/* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
-static const yytype_int16 yyrline[] =
+static const yytype_uint8 yyrline[] =
{
- 0, 106, 106, 106, 109, 113, 118, 127, 133, 140,
- 145, 149, 154, 166, 171, 176, 181, 186, 191, 196,
- 201, 206, 210, 214, 218, 222, 223, 228, 228, 228,
- 229, 229, 230, 230, 231, 231, 232, 232, 233, 233,
- 234, 234, 235, 235, 236, 236, 237, 237, 240, 241,
- 242, 243, 244, 245, 246, 247, 248, 249, 250, 251,
- 252, 253, 254, 255, 256
+ 0, 106, 106, 106, 109, 113, 118, 123, 129, 136,
+ 141, 145, 150, 162, 167, 172, 177, 182, 187, 192,
+ 197, 202, 206, 210, 214, 218, 219, 224, 224, 224,
+ 225, 225, 226, 226, 227, 227, 228, 228, 229, 229,
+ 230, 230, 231, 231, 232, 232, 233, 233, 236, 237,
+ 238, 239, 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 252
};
#endif
@@ -666,19 +666,19 @@ yysymbol_name (yysymbol_kind_t yysymbol)
STATE-NUM. */
static const yytype_int16 yypact[] =
{
- -39, 21, -39, 1, -39, -20, -39, -39, -39, -39,
+ -39, 21, -39, 5, -39, -23, -39, -39, -39, -39,
-39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, -39, -24, -18, 20, -8,
- -3, 40, -39, 15, 16, 17, 19, 34, -39, -39,
- -39, -39, -39, -39, 59, -39, -39, -39, -39, -39,
- 36, 37, 38, -39, -39, -39, -39, -39, -39, 77,
- 115, 130, 168, 183, -39, -39, -39, -39, -39, -39,
+ -39, -39, -39, -39, -39, -39, -25, -19, 20, -8,
+ -15, -22, -39, -6, 14, 15, 16, 17, -39, -39,
+ -39, -39, -39, -39, 59, 49, 51, -39, 63, 64,
+ 35, 36, 37, -39, -39, -39, -39, -39, -39, 74,
+ 112, 127, 165, 180, -39, -39, -39, -39, -39, -39,
-39, -39, -39, -39, -39, -39, -39, -39, -39, -39,
- -39, -39, -39, 221, 236, 274, 289, -21, 26, -39,
- 327, 342, 380, 395, 433, 448, -39, -39, -39, -39,
- -39, -39, -39, -39, -39, 39, 41, 42, 486, -39,
- -39, -39, -39, -39, -39, 18, -39, -39, -39, 43,
- 501, 539, -39, -39, -39, 554, -39
+ -39, -39, -39, -39, -39, -39, -39, -20, 43, -39,
+ 218, 233, 271, 286, 324, 339, -39, -39, -39, -39,
+ -39, 39, 40, 41, 377, -39, -39, -39, -39, -39,
+ -39, 46, 78, -39, -39, 50, -39, 392, 79, -39,
+ -39
};
/* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
@@ -690,15 +690,15 @@ static const yytype_int8 yydefact[] =
30, 33, 32, 34, 36, 38, 42, 40, 44, 35,
37, 39, 43, 41, 45, 46, 0, 0, 0, 0,
0, 0, 3, 0, 0, 0, 0, 0, 46, 46,
- 46, 46, 26, 46, 0, 46, 46, 4, 46, 46,
+ 46, 46, 26, 46, 0, 0, 0, 4, 0, 0,
0, 0, 0, 46, 46, 46, 46, 46, 46, 0,
0, 0, 0, 0, 15, 57, 56, 64, 62, 58,
59, 60, 61, 63, 55, 48, 49, 50, 51, 52,
- 53, 54, 47, 0, 0, 0, 0, 0, 0, 46,
+ 53, 54, 47, 10, 13, 9, 6, 0, 0, 46,
0, 0, 0, 0, 0, 0, 21, 22, 23, 24,
- 14, 10, 13, 9, 6, 0, 0, 0, 0, 5,
- 16, 17, 18, 19, 20, 0, 46, 46, 11, 0,
- 0, 0, 46, 7, 12, 0, 8
+ 14, 0, 0, 0, 0, 5, 16, 17, 18, 19,
+ 20, 0, 0, 46, 11, 0, 7, 0, 0, 12,
+ 8
};
/* YYPGOTO[NTERM-NUM]. */
@@ -720,81 +720,70 @@ static const yytype_int8 yydefgoto[] =
number is the opposite. If YYTABLE_NINF, syntax error. */
static const yytype_int8 yytable[] =
{
- 59, 60, 61, 62, 42, 63, 105, 83, 84, 106,
- 85, 86, 43, 45, 46, 90, 91, 92, 93, 94,
- 95, 2, 3, 47, 4, 49, 50, 5, 6, 7,
+ 59, 60, 61, 62, 51, 63, 52, 101, 42, 43,
+ 102, 53, 45, 46, 50, 90, 91, 92, 93, 94,
+ 95, 2, 3, 47, 4, 49, 54, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
- 18, 19, 20, 21, 22, 23, 24, 54, 119, 55,
- 56, 108, 57, 48, 107, 25, 26, 27, 28, 29,
- 30, 31, 64, 65, 66, 67, 51, 58, 52, 87,
- 88, 89, 115, 53, 116, 117, 122, 0, 120, 121,
- 96, 65, 66, 67, 125, 68, 69, 70, 71, 72,
+ 18, 19, 20, 21, 22, 23, 24, 55, 56, 57,
+ 58, 104, 83, 48, 84, 25, 26, 27, 28, 29,
+ 30, 31, 64, 65, 66, 67, 85, 86, 87, 88,
+ 89, 103, 111, 112, 113, 117, 115, 96, 65, 66,
+ 67, 116, 120, 118, 0, 68, 69, 70, 71, 72,
73, 74, 75, 0, 76, 77, 78, 79, 80, 81,
- 0, 0, 0, 68, 69, 70, 71, 72, 73, 74,
- 75, 0, 76, 77, 78, 79, 80, 81, 97, 65,
+ 68, 69, 70, 71, 72, 73, 74, 75, 0, 76,
+ 77, 78, 79, 80, 81, 97, 65, 66, 67, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 98, 65, 66, 67, 0, 0, 0, 0, 68, 69,
+ 70, 71, 72, 73, 74, 75, 0, 76, 77, 78,
+ 79, 80, 81, 68, 69, 70, 71, 72, 73, 74,
+ 75, 0, 76, 77, 78, 79, 80, 81, 99, 65,
66, 67, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 98, 65, 66, 67, 0, 0, 0,
+ 0, 0, 0, 100, 65, 66, 67, 0, 0, 0,
0, 68, 69, 70, 71, 72, 73, 74, 75, 0,
76, 77, 78, 79, 80, 81, 68, 69, 70, 71,
72, 73, 74, 75, 0, 76, 77, 78, 79, 80,
- 81, 99, 65, 66, 67, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 100, 65, 66, 67,
+ 81, 105, 65, 66, 67, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 106, 65, 66, 67,
0, 0, 0, 0, 68, 69, 70, 71, 72, 73,
74, 75, 0, 76, 77, 78, 79, 80, 81, 68,
69, 70, 71, 72, 73, 74, 75, 0, 76, 77,
- 78, 79, 80, 81, 101, 65, 66, 67, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 102,
+ 78, 79, 80, 81, 107, 65, 66, 67, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 108,
65, 66, 67, 0, 0, 0, 0, 68, 69, 70,
71, 72, 73, 74, 75, 0, 76, 77, 78, 79,
80, 81, 68, 69, 70, 71, 72, 73, 74, 75,
- 0, 76, 77, 78, 79, 80, 81, 103, 65, 66,
+ 0, 76, 77, 78, 79, 80, 81, 109, 65, 66,
67, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 104, 65, 66, 67, 0, 0, 0, 0,
+ 0, 0, 110, 65, 66, 67, 0, 0, 0, 0,
68, 69, 70, 71, 72, 73, 74, 75, 0, 76,
77, 78, 79, 80, 81, 68, 69, 70, 71, 72,
73, 74, 75, 0, 76, 77, 78, 79, 80, 81,
- 109, 65, 66, 67, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 110, 65, 66, 67, 0,
+ 114, 65, 66, 67, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 119, 65, 66, 67, 0,
0, 0, 0, 68, 69, 70, 71, 72, 73, 74,
75, 0, 76, 77, 78, 79, 80, 81, 68, 69,
70, 71, 72, 73, 74, 75, 0, 76, 77, 78,
- 79, 80, 81, 111, 65, 66, 67, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 112, 65,
- 66, 67, 0, 0, 0, 0, 68, 69, 70, 71,
- 72, 73, 74, 75, 0, 76, 77, 78, 79, 80,
- 81, 68, 69, 70, 71, 72, 73, 74, 75, 0,
- 76, 77, 78, 79, 80, 81, 113, 65, 66, 67,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 114, 65, 66, 67, 0, 0, 0, 0, 68,
- 69, 70, 71, 72, 73, 74, 75, 0, 76, 77,
- 78, 79, 80, 81, 68, 69, 70, 71, 72, 73,
- 74, 75, 0, 76, 77, 78, 79, 80, 81, 118,
- 65, 66, 67, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 123, 65, 66, 67, 0, 0,
- 0, 0, 68, 69, 70, 71, 72, 73, 74, 75,
- 0, 76, 77, 78, 79, 80, 81, 68, 69, 70,
- 71, 72, 73, 74, 75, 0, 76, 77, 78, 79,
- 80, 81, 124, 65, 66, 67, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 126, 65, 66,
- 67, 0, 0, 0, 0, 68, 69, 70, 71, 72,
- 73, 74, 75, 0, 76, 77, 78, 79, 80, 81,
- 68, 69, 70, 71, 72, 73, 74, 75, 0, 76,
- 77, 78, 79, 80, 81
+ 79, 80, 81
};
static const yytype_int8 yycheck[] =
{
- 38, 39, 40, 41, 3, 43, 27, 45, 46, 30,
- 48, 49, 32, 37, 32, 53, 54, 55, 56, 57,
- 58, 0, 1, 3, 3, 33, 29, 6, 7, 8,
+ 38, 39, 40, 41, 26, 43, 28, 27, 3, 32,
+ 30, 33, 37, 32, 29, 53, 54, 55, 56, 57,
+ 58, 0, 1, 3, 3, 33, 32, 6, 7, 8,
9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
- 19, 20, 21, 22, 23, 24, 25, 32, 30, 33,
- 33, 89, 33, 33, 28, 34, 35, 36, 37, 38,
- 39, 40, 3, 4, 5, 6, 26, 33, 28, 33,
- 33, 33, 33, 33, 33, 33, 33, -1, 116, 117,
- 3, 4, 5, 6, 122, 26, 27, 28, 29, 30,
+ 19, 20, 21, 22, 23, 24, 25, 33, 33, 33,
+ 33, 89, 3, 33, 3, 34, 35, 36, 37, 38,
+ 39, 40, 3, 4, 5, 6, 3, 3, 33, 33,
+ 33, 28, 33, 33, 33, 113, 30, 3, 4, 5,
+ 6, 3, 3, 33, -1, 26, 27, 28, 29, 30,
31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
- -1, -1, -1, 26, 27, 28, 29, 30, 31, 32,
+ 26, 27, 28, 29, 30, 31, 32, 33, -1, 35,
+ 36, 37, 38, 39, 40, 3, 4, 5, 6, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 3, 4, 5, 6, -1, -1, -1, -1, 26, 27,
+ 28, 29, 30, 31, 32, 33, -1, 35, 36, 37,
+ 38, 39, 40, 26, 27, 28, 29, 30, 31, 32,
33, -1, 35, 36, 37, 38, 39, 40, 3, 4,
5, 6, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 3, 4, 5, 6, -1, -1, -1,
@@ -822,28 +811,7 @@ static const yytype_int8 yycheck[] =
-1, -1, -1, 26, 27, 28, 29, 30, 31, 32,
33, -1, 35, 36, 37, 38, 39, 40, 26, 27,
28, 29, 30, 31, 32, 33, -1, 35, 36, 37,
- 38, 39, 40, 3, 4, 5, 6, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, 3, 4,
- 5, 6, -1, -1, -1, -1, 26, 27, 28, 29,
- 30, 31, 32, 33, -1, 35, 36, 37, 38, 39,
- 40, 26, 27, 28, 29, 30, 31, 32, 33, -1,
- 35, 36, 37, 38, 39, 40, 3, 4, 5, 6,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, 3, 4, 5, 6, -1, -1, -1, -1, 26,
- 27, 28, 29, 30, 31, 32, 33, -1, 35, 36,
- 37, 38, 39, 40, 26, 27, 28, 29, 30, 31,
- 32, 33, -1, 35, 36, 37, 38, 39, 40, 3,
- 4, 5, 6, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, 3, 4, 5, 6, -1, -1,
- -1, -1, 26, 27, 28, 29, 30, 31, 32, 33,
- -1, 35, 36, 37, 38, 39, 40, 26, 27, 28,
- 29, 30, 31, 32, 33, -1, 35, 36, 37, 38,
- 39, 40, 3, 4, 5, 6, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, 3, 4, 5,
- 6, -1, -1, -1, -1, 26, 27, 28, 29, 30,
- 31, 32, 33, -1, 35, 36, 37, 38, 39, 40,
- 26, 27, 28, 29, 30, 31, 32, 33, -1, 35,
- 36, 37, 38, 39, 40
+ 38, 39, 40
};
/* YYSTOS[STATE-NUM] -- The symbol kind of the accessing symbol of
@@ -858,11 +826,11 @@ static const yytype_int8 yystos[] =
29, 26, 28, 33, 32, 33, 33, 33, 33, 53,
53, 53, 53, 53, 3, 4, 5, 6, 26, 27,
28, 29, 30, 31, 32, 33, 35, 36, 37, 38,
- 39, 40, 54, 53, 53, 53, 53, 33, 33, 33,
+ 39, 40, 54, 3, 3, 3, 3, 33, 33, 33,
53, 53, 53, 53, 53, 53, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 27, 30, 28, 53, 3,
- 3, 3, 3, 3, 3, 33, 33, 33, 3, 30,
- 53, 53, 33, 3, 3, 53, 3
+ 3, 27, 30, 28, 53, 3, 3, 3, 3, 3,
+ 3, 33, 33, 33, 3, 30, 3, 53, 33, 3,
+ 3
};
/* YYR1[RULE-NUM] -- Symbol kind of the left-hand side of rule RULE-NUM. */
@@ -880,8 +848,8 @@ static const yytype_int8 yyr1[] =
/* YYR2[RULE-NUM] -- Number of symbols on the right-hand side of rule RULE-NUM. */
static const yytype_int8 yyr2[] =
{
- 0, 2, 0, 2, 2, 4, 4, 7, 9, 4,
- 4, 5, 7, 4, 4, 3, 4, 4, 4, 4,
+ 0, 2, 0, 2, 2, 4, 3, 6, 8, 3,
+ 3, 5, 7, 3, 4, 3, 4, 4, 4, 4,
4, 3, 3, 3, 3, 1, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 0, 2, 1, 1,
@@ -1361,19 +1329,19 @@ yydestruct (const char *yymsg,
case YYSYMBOL_STRING: /* STRING */
#line 100 "cmFortranParser.y"
{ free(((*yyvaluep).string)); }
-#line 1365 "cmFortranParser.cxx"
+#line 1333 "cmFortranParser.cxx"
break;
case YYSYMBOL_WORD: /* WORD */
#line 100 "cmFortranParser.y"
{ free(((*yyvaluep).string)); }
-#line 1371 "cmFortranParser.cxx"
+#line 1339 "cmFortranParser.cxx"
break;
case YYSYMBOL_CPP_INCLUDE_ANGLE: /* CPP_INCLUDE_ANGLE */
#line 100 "cmFortranParser.y"
{ free(((*yyvaluep).string)); }
-#line 1377 "cmFortranParser.cxx"
+#line 1345 "cmFortranParser.cxx"
break;
default:
@@ -1655,7 +1623,7 @@ yyreduce:
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
}
-#line 1659 "cmFortranParser.cxx"
+#line 1627 "cmFortranParser.cxx"
break;
case 5: /* stmt: USE WORD other EOSTMT */
@@ -1665,77 +1633,73 @@ yyreduce:
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1669 "cmFortranParser.cxx"
+#line 1637 "cmFortranParser.cxx"
break;
- case 6: /* stmt: MODULE WORD other EOSTMT */
+ case 6: /* stmt: MODULE WORD EOSTMT */
#line 118 "cmFortranParser.y"
- {
+ {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- if (cmsysString_strcasecmp((yyvsp[-2].string), "function") != 0 &&
- cmsysString_strcasecmp((yyvsp[-2].string), "procedure") != 0 &&
- cmsysString_strcasecmp((yyvsp[-2].string), "subroutine") != 0) {
- cmFortranParser_RuleModule(parser, (yyvsp[-2].string));
- }
- free((yyvsp[-2].string));
+ cmFortranParser_RuleModule(parser, (yyvsp[-1].string));
+ free((yyvsp[-1].string));
}
-#line 1683 "cmFortranParser.cxx"
+#line 1647 "cmFortranParser.cxx"
break;
- case 7: /* stmt: SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT */
-#line 127 "cmFortranParser.y"
- {
+ case 7: /* stmt: SUBMODULE LPAREN WORD RPAREN WORD EOSTMT */
+#line 123 "cmFortranParser.y"
+ {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleSubmodule(parser, (yyvsp[-4].string), (yyvsp[-2].string));
- free((yyvsp[-4].string));
- free((yyvsp[-2].string));
+ cmFortranParser_RuleSubmodule(parser, (yyvsp[-3].string), (yyvsp[-1].string));
+ free((yyvsp[-3].string));
+ free((yyvsp[-1].string));
}
-#line 1694 "cmFortranParser.cxx"
+#line 1658 "cmFortranParser.cxx"
break;
- case 8: /* stmt: SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT */
-#line 133 "cmFortranParser.y"
- {
+ case 8: /* stmt: SUBMODULE LPAREN WORD COLON WORD RPAREN WORD EOSTMT */
+#line 129 "cmFortranParser.y"
+ {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-6].string), (yyvsp[-4].string), (yyvsp[-2].string));
- free((yyvsp[-6].string));
- free((yyvsp[-4].string));
- free((yyvsp[-2].string));
+ cmFortranParser_RuleSubmoduleNested(parser, (yyvsp[-5].string), (yyvsp[-3].string), (yyvsp[-1].string));
+ free((yyvsp[-5].string));
+ free((yyvsp[-3].string));
+ free((yyvsp[-1].string));
}
-#line 1706 "cmFortranParser.cxx"
+#line 1670 "cmFortranParser.cxx"
break;
- case 9: /* stmt: INTERFACE WORD other EOSTMT */
-#line 140 "cmFortranParser.y"
- {
+ case 9: /* stmt: INTERFACE WORD EOSTMT */
+#line 136 "cmFortranParser.y"
+ {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
- free((yyvsp[-2].string));
+ free((yyvsp[-1].string));
}
-#line 1716 "cmFortranParser.cxx"
+#line 1680 "cmFortranParser.cxx"
break;
- case 10: /* stmt: END INTERFACE other EOSTMT */
-#line 145 "cmFortranParser.y"
- {
+ case 10: /* stmt: END INTERFACE EOSTMT */
+#line 141 "cmFortranParser.y"
+ {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, false);
}
-#line 1725 "cmFortranParser.cxx"
+#line 1689 "cmFortranParser.cxx"
break;
case 11: /* stmt: USE DCOLON WORD other EOSTMT */
-#line 149 "cmFortranParser.y"
+#line 145 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUse(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1735 "cmFortranParser.cxx"
+#line 1699 "cmFortranParser.cxx"
break;
case 12: /* stmt: USE COMMA WORD DCOLON WORD other EOSTMT */
-#line 154 "cmFortranParser.y"
+#line 150 "cmFortranParser.y"
{
if (cmsysString_strcasecmp((yyvsp[-4].string), "non_intrinsic") == 0) {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
@@ -1748,139 +1712,139 @@ yyreduce:
free((yyvsp[-4].string));
free((yyvsp[-2].string));
}
-#line 1752 "cmFortranParser.cxx"
+#line 1716 "cmFortranParser.cxx"
break;
- case 13: /* stmt: INCLUDE STRING other EOSTMT */
-#line 166 "cmFortranParser.y"
- {
+ case 13: /* stmt: INCLUDE STRING EOSTMT */
+#line 162 "cmFortranParser.y"
+ {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
- free((yyvsp[-2].string));
+ cmFortranParser_RuleInclude(parser, (yyvsp[-1].string));
+ free((yyvsp[-1].string));
}
-#line 1762 "cmFortranParser.cxx"
+#line 1726 "cmFortranParser.cxx"
break;
case 14: /* stmt: CPP_LINE_DIRECTIVE STRING other EOSTMT */
-#line 171 "cmFortranParser.y"
+#line 167 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleLineDirective(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1772 "cmFortranParser.cxx"
+#line 1736 "cmFortranParser.cxx"
break;
case 15: /* stmt: CPP_INCLUDE_ANGLE other EOSTMT */
-#line 176 "cmFortranParser.y"
+#line 172 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1782 "cmFortranParser.cxx"
+#line 1746 "cmFortranParser.cxx"
break;
case 16: /* stmt: include STRING other EOSTMT */
-#line 181 "cmFortranParser.y"
+#line 177 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1792 "cmFortranParser.cxx"
+#line 1756 "cmFortranParser.cxx"
break;
case 17: /* stmt: define WORD other EOSTMT */
-#line 186 "cmFortranParser.y"
+#line 182 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleDefine(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1802 "cmFortranParser.cxx"
+#line 1766 "cmFortranParser.cxx"
break;
case 18: /* stmt: undef WORD other EOSTMT */
-#line 191 "cmFortranParser.y"
+#line 187 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleUndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1812 "cmFortranParser.cxx"
+#line 1776 "cmFortranParser.cxx"
break;
case 19: /* stmt: ifdef WORD other EOSTMT */
-#line 196 "cmFortranParser.y"
+#line 192 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfdef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1822 "cmFortranParser.cxx"
+#line 1786 "cmFortranParser.cxx"
break;
case 20: /* stmt: ifndef WORD other EOSTMT */
-#line 201 "cmFortranParser.y"
+#line 197 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIfndef(parser, (yyvsp[-2].string));
free((yyvsp[-2].string));
}
-#line 1832 "cmFortranParser.cxx"
+#line 1796 "cmFortranParser.cxx"
break;
case 21: /* stmt: if other EOSTMT */
-#line 206 "cmFortranParser.y"
+#line 202 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleIf(parser);
}
-#line 1841 "cmFortranParser.cxx"
+#line 1805 "cmFortranParser.cxx"
break;
case 22: /* stmt: elif other EOSTMT */
-#line 210 "cmFortranParser.y"
+#line 206 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElif(parser);
}
-#line 1850 "cmFortranParser.cxx"
+#line 1814 "cmFortranParser.cxx"
break;
case 23: /* stmt: else other EOSTMT */
-#line 214 "cmFortranParser.y"
+#line 210 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleElse(parser);
}
-#line 1859 "cmFortranParser.cxx"
+#line 1823 "cmFortranParser.cxx"
break;
case 24: /* stmt: endif other EOSTMT */
-#line 218 "cmFortranParser.y"
+#line 214 "cmFortranParser.y"
{
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleEndif(parser);
}
-#line 1868 "cmFortranParser.cxx"
+#line 1832 "cmFortranParser.cxx"
break;
case 48: /* misc_code: WORD */
-#line 240 "cmFortranParser.y"
+#line 236 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1874 "cmFortranParser.cxx"
+#line 1838 "cmFortranParser.cxx"
break;
case 55: /* misc_code: STRING */
-#line 247 "cmFortranParser.y"
+#line 243 "cmFortranParser.y"
{ free ((yyvsp[0].string)); }
-#line 1880 "cmFortranParser.cxx"
+#line 1844 "cmFortranParser.cxx"
break;
-#line 1884 "cmFortranParser.cxx"
+#line 1848 "cmFortranParser.cxx"
default: break;
}
@@ -2104,6 +2068,6 @@ yyreturnlab:
return yyresult;
}
-#line 259 "cmFortranParser.y"
+#line 255 "cmFortranParser.y"
/* End of grammar */
diff --git a/Source/LexerParser/cmFortranParser.y b/Source/LexerParser/cmFortranParser.y
index 07ca630..a5c8976 100644
--- a/Source/LexerParser/cmFortranParser.y
+++ b/Source/LexerParser/cmFortranParser.y
@@ -115,34 +115,30 @@ stmt:
cmFortranParser_RuleUse(parser, $2);
free($2);
}
-| MODULE WORD other EOSTMT {
+| MODULE WORD EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
- if (cmsysString_strcasecmp($2, "function") != 0 &&
- cmsysString_strcasecmp($2, "procedure") != 0 &&
- cmsysString_strcasecmp($2, "subroutine") != 0) {
- cmFortranParser_RuleModule(parser, $2);
- }
+ cmFortranParser_RuleModule(parser, $2);
free($2);
}
-| SUBMODULE LPAREN WORD RPAREN WORD other EOSTMT {
+| SUBMODULE LPAREN WORD RPAREN WORD EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmodule(parser, $3, $5);
free($3);
free($5);
}
-| SUBMODULE LPAREN WORD COLON WORD RPAREN WORD other EOSTMT {
+| SUBMODULE LPAREN WORD COLON WORD RPAREN WORD EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleSubmoduleNested(parser, $3, $5, $7);
free($3);
free($5);
free($7);
}
-| INTERFACE WORD other EOSTMT {
+| INTERFACE WORD EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, true);
free($2);
}
-| END INTERFACE other EOSTMT {
+| END INTERFACE EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_SetInInterface(parser, false);
}
@@ -163,7 +159,7 @@ stmt:
free($3);
free($5);
}
-| INCLUDE STRING other EOSTMT {
+| INCLUDE STRING EOSTMT {
cmFortranParser* parser = cmFortran_yyget_extra(yyscanner);
cmFortranParser_RuleInclude(parser, $2);
free($2);
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
index f3c4a8b..707eaae 100644
--- a/Source/QtDialog/FirstConfigure.cxx
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -244,7 +244,8 @@ void StartCompilerSetup::onGeneratorChanged(int index)
if (!DefaultGeneratorPlatform.isEmpty()) {
int platform_index = platforms.indexOf(DefaultGeneratorPlatform);
if (platform_index != -1) {
- this->PlatformOptions->setCurrentIndex(platform_index);
+ // The index is off-by-one due to the first empty item added above.
+ this->PlatformOptions->setCurrentIndex(platform_index + 1);
}
}
} else {
diff --git a/Source/cmArgumentParser.cxx b/Source/cmArgumentParser.cxx
index 4624f1c..ad57a88 100644
--- a/Source/cmArgumentParser.cxx
+++ b/Source/cmArgumentParser.cxx
@@ -4,9 +4,14 @@
#include <algorithm>
+#include "cmArgumentParserTypes.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmStringAlgorithms.h"
+
namespace ArgumentParser {
-auto ActionMap::Emplace(cm::string_view name, Action action)
+auto KeywordActionMap::Emplace(cm::string_view name, KeywordAction action)
-> std::pair<iterator, bool>
{
auto const it =
@@ -19,7 +24,7 @@ auto ActionMap::Emplace(cm::string_view name, Action action)
: std::make_pair(this->emplace(it, name, std::move(action)), true);
}
-auto ActionMap::Find(cm::string_view name) const -> const_iterator
+auto KeywordActionMap::Find(cm::string_view name) const -> const_iterator
{
auto const it =
std::lower_bound(this->begin(), this->end(), name,
@@ -29,68 +34,171 @@ auto ActionMap::Find(cm::string_view name) const -> const_iterator
return (it != this->end() && it->first == name) ? it : this->end();
}
+auto PositionActionMap::Emplace(std::size_t pos, PositionAction action)
+ -> std::pair<iterator, bool>
+{
+ auto const it = std::lower_bound(
+ this->begin(), this->end(), pos,
+ [](value_type const& elem, std::size_t k) { return elem.first < k; });
+ return (it != this->end() && it->first == pos)
+ ? std::make_pair(it, false)
+ : std::make_pair(this->emplace(it, pos, std::move(action)), true);
+}
+
+auto PositionActionMap::Find(std::size_t pos) const -> const_iterator
+{
+ auto const it = std::lower_bound(
+ this->begin(), this->end(), pos,
+ [](value_type const& elem, std::size_t k) { return elem.first < k; });
+ return (it != this->end() && it->first == pos) ? it : this->end();
+}
+
+void Instance::Bind(std::function<Continue(cm::string_view)> f,
+ ExpectAtLeast expect)
+{
+ this->KeywordValueFunc = std::move(f);
+ this->KeywordValuesExpected = expect.Count;
+}
+
void Instance::Bind(bool& val)
{
val = true;
- this->CurrentString = nullptr;
- this->CurrentList = nullptr;
- this->ExpectValue = false;
+ this->Bind(nullptr, ExpectAtLeast{ 0 });
}
void Instance::Bind(std::string& val)
{
- this->CurrentString = &val;
- this->CurrentList = nullptr;
- this->ExpectValue = true;
+ this->Bind(
+ [&val](cm::string_view arg) -> Continue {
+ val = std::string(arg);
+ return Continue::No;
+ },
+ ExpectAtLeast{ 1 });
+}
+
+void Instance::Bind(NonEmpty<std::string>& val)
+{
+ this->Bind(
+ [this, &val](cm::string_view arg) -> Continue {
+ if (arg.empty() && this->ParseResults) {
+ this->ParseResults->AddKeywordError(this->Keyword,
+ " empty string not allowed\n");
+ }
+ val.assign(std::string(arg));
+ return Continue::No;
+ },
+ ExpectAtLeast{ 1 });
}
-void Instance::Bind(StringList& val)
+void Instance::Bind(Maybe<std::string>& val)
{
- this->CurrentString = nullptr;
- this->CurrentList = &val;
- this->ExpectValue = true;
+ this->Bind(
+ [&val](cm::string_view arg) -> Continue {
+ static_cast<std::string&>(val) = std::string(arg);
+ return Continue::No;
+ },
+ ExpectAtLeast{ 0 });
}
-void Instance::Bind(MultiStringList& val)
+void Instance::Bind(MaybeEmpty<std::vector<std::string>>& val)
{
- this->CurrentString = nullptr;
- this->CurrentList = (static_cast<void>(val.emplace_back()), &val.back());
- this->ExpectValue = false;
+ this->Bind(
+ [&val](cm::string_view arg) -> Continue {
+ val.emplace_back(arg);
+ return Continue::Yes;
+ },
+ ExpectAtLeast{ 0 });
}
-void Instance::Consume(cm::string_view arg, void* result,
- std::vector<std::string>* unparsedArguments,
- std::vector<std::string>* keywordsMissingValue,
- std::vector<std::string>* parsedKeywords)
+void Instance::Bind(NonEmpty<std::vector<std::string>>& val)
{
- auto const it = this->Bindings.Find(arg);
- if (it != this->Bindings.end()) {
- if (parsedKeywords != nullptr) {
- parsedKeywords->emplace_back(arg);
+ this->Bind(
+ [&val](cm::string_view arg) -> Continue {
+ val.emplace_back(arg);
+ return Continue::Yes;
+ },
+ ExpectAtLeast{ 1 });
+}
+
+void Instance::Bind(std::vector<std::vector<std::string>>& multiVal)
+{
+ multiVal.emplace_back();
+ std::vector<std::string>& val = multiVal.back();
+ this->Bind(
+ [&val](cm::string_view arg) -> Continue {
+ val.emplace_back(arg);
+ return Continue::Yes;
+ },
+ ExpectAtLeast{ 0 });
+}
+
+void Instance::Consume(std::size_t pos, cm::string_view arg)
+{
+ auto const it = this->Bindings.Keywords.Find(arg);
+ if (it != this->Bindings.Keywords.end()) {
+ this->FinishKeyword();
+ this->Keyword = it->first;
+ this->KeywordValuesSeen = 0;
+ this->DoneWithPositional = true;
+ if (this->Bindings.ParsedKeyword) {
+ this->Bindings.ParsedKeyword(*this, it->first);
}
- it->second(*this, result);
- if (this->ExpectValue && keywordsMissingValue != nullptr) {
- keywordsMissingValue->emplace_back(arg);
+ it->second(*this);
+ return;
+ }
+
+ if (this->KeywordValueFunc) {
+ switch (this->KeywordValueFunc(arg)) {
+ case Continue::Yes:
+ break;
+ case Continue::No:
+ this->KeywordValueFunc = nullptr;
+ break;
}
+ ++this->KeywordValuesSeen;
return;
}
- if (this->CurrentString != nullptr) {
- this->CurrentString->assign(std::string(arg));
- this->CurrentString = nullptr;
- this->CurrentList = nullptr;
- } else if (this->CurrentList != nullptr) {
- this->CurrentList->emplace_back(arg);
- } else if (unparsedArguments != nullptr) {
- unparsedArguments->emplace_back(arg);
+ if (!this->DoneWithPositional) {
+ auto const pit = this->Bindings.Positions.Find(pos);
+ if (pit != this->Bindings.Positions.end()) {
+ pit->second(*this, pos, arg);
+ return;
+ }
+ }
+
+ if (this->UnparsedArguments != nullptr) {
+ this->UnparsedArguments->emplace_back(arg);
}
+}
- if (this->ExpectValue) {
- if (keywordsMissingValue != nullptr) {
- keywordsMissingValue->pop_back();
+void Instance::FinishKeyword()
+{
+ if (this->Keyword.empty()) {
+ return;
+ }
+ if (this->KeywordValuesSeen < this->KeywordValuesExpected) {
+ if (this->ParseResults != nullptr) {
+ this->ParseResults->AddKeywordError(this->Keyword,
+ " missing required value\n");
}
- this->ExpectValue = false;
+ if (this->Bindings.KeywordMissingValue) {
+ this->Bindings.KeywordMissingValue(*this, this->Keyword);
+ }
+ }
+}
+
+bool ParseResult::MaybeReportError(cmMakefile& mf) const
+{
+ if (*this) {
+ return false;
+ }
+ std::string e;
+ for (auto const& ke : this->KeywordErrors) {
+ e = cmStrCat(e, "Error after keyword \"", ke.first, "\":\n", ke.second);
}
+ mf.IssueMessage(MessageType::FATAL_ERROR, e);
+ return true;
}
} // namespace ArgumentParser
diff --git a/Source/cmArgumentParser.h b/Source/cmArgumentParser.h
index 71ed844..fdf54fb 100644
--- a/Source/cmArgumentParser.h
+++ b/Source/cmArgumentParser.h
@@ -5,59 +5,220 @@
#include "cmConfigure.h" // IWYU pragma: keep
#include <cassert>
+#include <cstddef>
#include <functional>
+#include <map>
#include <string>
#include <utility>
#include <vector>
+#include <cm/optional>
#include <cm/string_view>
+#include <cm/type_traits>
#include <cmext/string_view>
+#include "cmArgumentParserTypes.h" // IWYU pragma: keep
+
+template <typename Result>
+class cmArgumentParser; // IWYU pragma: keep
+
+class cmMakefile;
+
namespace ArgumentParser {
-using StringList = std::vector<std::string>;
-using MultiStringList = std::vector<StringList>;
+class ParseResult
+{
+ std::map<cm::string_view, std::string> KeywordErrors;
+
+public:
+ explicit operator bool() const { return this->KeywordErrors.empty(); }
+
+ void AddKeywordError(cm::string_view key, cm::string_view text)
+
+ {
+ this->KeywordErrors[key] += text;
+ }
+
+ std::map<cm::string_view, std::string> const& GetKeywordErrors() const
+ {
+ return this->KeywordErrors;
+ }
+
+ bool MaybeReportError(cmMakefile& mf) const;
+};
+
+template <typename Result>
+typename std::enable_if<std::is_base_of<ParseResult, Result>::value,
+ ParseResult*>::type
+AsParseResultPtr(Result& result)
+{
+ return &result;
+}
+
+template <typename Result>
+typename std::enable_if<!std::is_base_of<ParseResult, Result>::value,
+ ParseResult*>::type
+AsParseResultPtr(Result&)
+{
+ return nullptr;
+}
+
+enum class Continue
+{
+ No,
+ Yes,
+};
+
+struct ExpectAtLeast
+{
+ std::size_t Count = 0;
+
+ ExpectAtLeast(std::size_t count)
+ : Count(count)
+ {
+ }
+};
class Instance;
-using Action = std::function<void(Instance&, void*)>;
+using KeywordAction = std::function<void(Instance&)>;
+using KeywordNameAction = std::function<void(Instance&, cm::string_view)>;
+using PositionAction =
+ std::function<void(Instance&, std::size_t, cm::string_view)>;
-// using ActionMap = cm::flat_map<cm::string_view, Action>;
-class ActionMap : public std::vector<std::pair<cm::string_view, Action>>
+// using KeywordActionMap = cm::flat_map<cm::string_view, KeywordAction>;
+class KeywordActionMap
+ : public std::vector<std::pair<cm::string_view, KeywordAction>>
{
public:
- std::pair<iterator, bool> Emplace(cm::string_view name, Action action);
+ std::pair<iterator, bool> Emplace(cm::string_view name,
+ KeywordAction action);
const_iterator Find(cm::string_view name) const;
};
+// using PositionActionMap = cm::flat_map<cm::string_view, PositionAction>;
+class PositionActionMap
+ : public std::vector<std::pair<std::size_t, PositionAction>>
+{
+public:
+ std::pair<iterator, bool> Emplace(std::size_t pos, PositionAction action);
+ const_iterator Find(std::size_t pos) const;
+};
+
+class ActionMap
+{
+public:
+ KeywordActionMap Keywords;
+ KeywordNameAction KeywordMissingValue;
+ KeywordNameAction ParsedKeyword;
+ PositionActionMap Positions;
+};
+
+class Base
+{
+public:
+ using ExpectAtLeast = ArgumentParser::ExpectAtLeast;
+ using Continue = ArgumentParser::Continue;
+ using Instance = ArgumentParser::Instance;
+ using ParseResult = ArgumentParser::ParseResult;
+
+ ArgumentParser::ActionMap Bindings;
+
+ bool MaybeBind(cm::string_view name, KeywordAction action)
+ {
+ return this->Bindings.Keywords.Emplace(name, std::move(action)).second;
+ }
+
+ void Bind(cm::string_view name, KeywordAction action)
+ {
+ bool const inserted = this->MaybeBind(name, std::move(action));
+ assert(inserted);
+ static_cast<void>(inserted);
+ }
+
+ void BindParsedKeyword(KeywordNameAction action)
+ {
+ assert(!this->Bindings.ParsedKeyword);
+ this->Bindings.ParsedKeyword = std::move(action);
+ }
+
+ void BindKeywordMissingValue(KeywordNameAction action)
+ {
+ assert(!this->Bindings.KeywordMissingValue);
+ this->Bindings.KeywordMissingValue = std::move(action);
+ }
+
+ void Bind(std::size_t pos, PositionAction action)
+ {
+ bool const inserted =
+ this->Bindings.Positions.Emplace(pos, std::move(action)).second;
+ assert(inserted);
+ static_cast<void>(inserted);
+ }
+};
+
class Instance
{
public:
- Instance(ActionMap const& bindings)
+ Instance(ActionMap const& bindings, ParseResult* parseResult,
+ std::vector<std::string>* unparsedArguments, void* result = nullptr)
: Bindings(bindings)
+ , ParseResults(parseResult)
+ , UnparsedArguments(unparsedArguments)
+ , Result(result)
{
}
+ void Bind(std::function<Continue(cm::string_view)> f, ExpectAtLeast expect);
void Bind(bool& val);
void Bind(std::string& val);
- void Bind(StringList& val);
- void Bind(MultiStringList& val);
+ void Bind(NonEmpty<std::string>& val);
+ void Bind(Maybe<std::string>& val);
+ void Bind(MaybeEmpty<std::vector<std::string>>& val);
+ void Bind(NonEmpty<std::vector<std::string>>& val);
+ void Bind(std::vector<std::vector<std::string>>& val);
+
+ // cm::optional<> records the presence the keyword to which it binds.
+ template <typename T>
+ void Bind(cm::optional<T>& optVal)
+ {
+ if (!optVal) {
+ optVal.emplace();
+ }
+ this->Bind(*optVal);
+ }
- void Consume(cm::string_view arg, void* result,
- std::vector<std::string>* unparsedArguments,
- std::vector<std::string>* keywordsMissingValue,
- std::vector<std::string>* parsedKeywords);
+ template <typename Range>
+ void Parse(Range const& args, std::size_t pos = 0)
+ {
+ for (cm::string_view arg : args) {
+ this->Consume(pos++, arg);
+ }
+ this->FinishKeyword();
+ }
private:
ActionMap const& Bindings;
- std::string* CurrentString = nullptr;
- StringList* CurrentList = nullptr;
- bool ExpectValue = false;
+ ParseResult* ParseResults = nullptr;
+ std::vector<std::string>* UnparsedArguments = nullptr;
+ void* Result = nullptr;
+
+ cm::string_view Keyword;
+ std::size_t KeywordValuesSeen = 0;
+ std::size_t KeywordValuesExpected = 0;
+ std::function<Continue(cm::string_view)> KeywordValueFunc;
+ bool DoneWithPositional = false;
+
+ void Consume(std::size_t pos, cm::string_view arg);
+ void FinishKeyword();
+
+ template <typename Result>
+ friend class ::cmArgumentParser;
};
} // namespace ArgumentParser
template <typename Result>
-class cmArgumentParser
+class cmArgumentParser : private ArgumentParser::Base
{
public:
// I *think* this function could be made `constexpr` when the code is
@@ -65,83 +226,194 @@ public:
template <typename T>
cmArgumentParser& Bind(cm::static_string_view name, T Result::*member)
{
- bool const inserted =
- this->Bindings
- .Emplace(name,
- [member](ArgumentParser::Instance& instance, void* result) {
- instance.Bind(static_cast<Result*>(result)->*member);
- })
- .second;
- assert(inserted), (void)inserted;
+ this->Base::Bind(name, [member](Instance& instance) {
+ instance.Bind(static_cast<Result*>(instance.Result)->*member);
+ });
+ return *this;
+ }
+
+ cmArgumentParser& Bind(cm::static_string_view name,
+ Continue (Result::*member)(cm::string_view),
+ ExpectAtLeast expect = { 1 })
+ {
+ this->Base::Bind(name, [member, expect](Instance& instance) {
+ Result* result = static_cast<Result*>(instance.Result);
+ instance.Bind(
+ [result, member](cm::string_view arg) -> Continue {
+ return (result->*member)(arg);
+ },
+ expect);
+ });
+ return *this;
+ }
+
+ cmArgumentParser& Bind(cm::static_string_view name,
+ Continue (Result::*member)(cm::string_view,
+ cm::string_view),
+ ExpectAtLeast expect = { 1 })
+ {
+ this->Base::Bind(name, [member, expect](Instance& instance) {
+ Result* result = static_cast<Result*>(instance.Result);
+ cm::string_view keyword = instance.Keyword;
+ instance.Bind(
+ [result, member, keyword](cm::string_view arg) -> Continue {
+ return (result->*member)(keyword, arg);
+ },
+ expect);
+ });
+ return *this;
+ }
+
+ cmArgumentParser& Bind(cm::static_string_view name,
+ std::function<Continue(Result&, cm::string_view)> f,
+ ExpectAtLeast expect = { 1 })
+ {
+ this->Base::Bind(name, [f, expect](Instance& instance) {
+ Result* result = static_cast<Result*>(instance.Result);
+ instance.Bind(
+ [result, &f](cm::string_view arg) -> Continue {
+ return f(*result, arg);
+ },
+ expect);
+ });
+ return *this;
+ }
+
+ cmArgumentParser& Bind(
+ cm::static_string_view name,
+ std::function<Continue(Result&, cm::string_view, cm::string_view)> f,
+ ExpectAtLeast expect = { 1 })
+ {
+ this->Base::Bind(name, [f, expect](Instance& instance) {
+ Result* result = static_cast<Result*>(instance.Result);
+ cm::string_view keyword = instance.Keyword;
+ instance.Bind(
+ [result, keyword, &f](cm::string_view arg) -> Continue {
+ return f(*result, keyword, arg);
+ },
+ expect);
+ });
+ return *this;
+ }
+
+ cmArgumentParser& Bind(std::size_t position,
+ cm::optional<std::string> Result::*member)
+ {
+ this->Base::Bind(
+ position,
+ [member](Instance& instance, std::size_t, cm::string_view arg) {
+ Result* result = static_cast<Result*>(instance.Result);
+ result->*member = arg;
+ });
+ return *this;
+ }
+
+ cmArgumentParser& BindParsedKeywords(
+ std::vector<cm::string_view> Result::*member)
+ {
+ this->Base::BindParsedKeyword(
+ [member](Instance& instance, cm::string_view arg) {
+ (static_cast<Result*>(instance.Result)->*member).emplace_back(arg);
+ });
return *this;
}
template <typename Range>
- void Parse(Result& result, Range const& args,
- std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr,
- std::vector<std::string>* parsedKeywords = nullptr) const
+ bool Parse(Result& result, Range const& args,
+ std::vector<std::string>* unparsedArguments,
+ std::size_t pos = 0) const
{
- ArgumentParser::Instance instance(this->Bindings);
- for (cm::string_view arg : args) {
- instance.Consume(arg, &result, unparsedArguments, keywordsMissingValue,
- parsedKeywords);
- }
+ using ArgumentParser::AsParseResultPtr;
+ ParseResult* parseResultPtr = AsParseResultPtr(result);
+ Instance instance(this->Bindings, parseResultPtr, unparsedArguments,
+ &result);
+ instance.Parse(args, pos);
+ return parseResultPtr ? static_cast<bool>(*parseResultPtr) : true;
}
template <typename Range>
- Result Parse(Range const& args,
- std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr,
- std::vector<std::string>* parsedKeywords = nullptr) const
+ Result Parse(Range const& args, std::vector<std::string>* unparsedArguments,
+ std::size_t pos = 0) const
{
Result result;
- this->Parse(result, args, unparsedArguments, keywordsMissingValue,
- parsedKeywords);
+ this->Parse(result, args, unparsedArguments, pos);
return result;
}
-
-private:
- ArgumentParser::ActionMap Bindings;
};
template <>
-class cmArgumentParser<void>
+class cmArgumentParser<void> : private ArgumentParser::Base
{
public:
template <typename T>
cmArgumentParser& Bind(cm::static_string_view name, T& ref)
{
- bool const inserted = this->Bind(cm::string_view(name), ref);
- assert(inserted), (void)inserted;
+ this->Base::Bind(name, [&ref](Instance& instance) { instance.Bind(ref); });
+ return *this;
+ }
+
+ cmArgumentParser& Bind(cm::static_string_view name,
+ std::function<Continue(cm::string_view)> f,
+ ExpectAtLeast expect = { 1 })
+ {
+ this->Base::Bind(name, [f, expect](Instance& instance) {
+ instance.Bind([&f](cm::string_view arg) -> Continue { return f(arg); },
+ expect);
+ });
+ return *this;
+ }
+
+ cmArgumentParser& Bind(
+ cm::static_string_view name,
+ std::function<Continue(cm::string_view, cm::string_view)> f,
+ ExpectAtLeast expect = { 1 })
+ {
+ this->Base::Bind(name, [f, expect](Instance& instance) {
+ cm::string_view keyword = instance.Keyword;
+ instance.Bind(
+ [keyword, &f](cm::string_view arg) -> Continue {
+ return f(keyword, arg);
+ },
+ expect);
+ });
+ return *this;
+ }
+
+ cmArgumentParser& Bind(std::size_t position, cm::optional<std::string>& ref)
+ {
+ this->Base::Bind(position,
+ [&ref](Instance&, std::size_t, cm::string_view arg) {
+ ref = std::string(arg);
+ });
+ return *this;
+ }
+
+ cmArgumentParser& BindParsedKeywords(std::vector<cm::string_view>& ref)
+ {
+ this->Base::BindParsedKeyword(
+ [&ref](Instance&, cm::string_view arg) { ref.emplace_back(arg); });
return *this;
}
template <typename Range>
- void Parse(Range const& args,
- std::vector<std::string>* unparsedArguments = nullptr,
- std::vector<std::string>* keywordsMissingValue = nullptr,
- std::vector<std::string>* parsedKeywords = nullptr) const
+ ParseResult Parse(Range const& args,
+ std::vector<std::string>* unparsedArguments,
+ std::size_t pos = 0) const
{
- ArgumentParser::Instance instance(this->Bindings);
- for (cm::string_view arg : args) {
- instance.Consume(arg, nullptr, unparsedArguments, keywordsMissingValue,
- parsedKeywords);
- }
+ ParseResult parseResult;
+ Instance instance(this->Bindings, &parseResult, unparsedArguments);
+ instance.Parse(args, pos);
+ return parseResult;
}
protected:
+ using Base::Instance;
+ using Base::BindKeywordMissingValue;
+
template <typename T>
bool Bind(cm::string_view name, T& ref)
{
- return this->Bindings
- .Emplace(name,
- [&ref](ArgumentParser::Instance& instance, void*) {
- instance.Bind(ref);
- })
- .second;
+ return this->MaybeBind(name,
+ [&ref](Instance& instance) { instance.Bind(ref); });
}
-
-private:
- ArgumentParser::ActionMap Bindings;
};
diff --git a/Source/cmArgumentParserTypes.h b/Source/cmArgumentParserTypes.h
new file mode 100644
index 0000000..7daae09
--- /dev/null
+++ b/Source/cmArgumentParserTypes.h
@@ -0,0 +1,69 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#if defined(__SUNPRO_CC)
+
+# include <string>
+# include <vector>
+
+namespace ArgumentParser {
+
+template <typename T>
+struct Maybe;
+template <>
+struct Maybe<std::string> : public std::string
+{
+ using std::string::basic_string;
+};
+
+template <typename T>
+struct MaybeEmpty;
+template <typename T>
+struct MaybeEmpty<std::vector<T>> : public std::vector<T>
+{
+ using std::vector<T>::vector;
+};
+
+template <typename T>
+struct NonEmpty;
+template <typename T>
+struct NonEmpty<std::vector<T>> : public std::vector<T>
+{
+ using std::vector<T>::vector;
+};
+template <>
+struct NonEmpty<std::string> : public std::string
+{
+ using std::string::basic_string;
+};
+
+} // namespace ArgumentParser
+
+#else
+
+namespace ArgumentParser {
+
+template <typename T>
+struct Maybe : public T
+{
+ using T::T;
+};
+
+template <typename T>
+struct MaybeEmpty : public T
+{
+ using T::T;
+};
+
+template <typename T>
+struct NonEmpty : public T
+{
+ using T::T;
+};
+
+} // namespace ArgumentParser
+
+#endif
diff --git a/Source/cmBlockCommand.cxx b/Source/cmBlockCommand.cxx
new file mode 100644
index 0000000..ec79149
--- /dev/null
+++ b/Source/cmBlockCommand.cxx
@@ -0,0 +1,197 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmBlockCommand.h"
+
+#include <cstdint> // IWYU pragma: keep
+#include <utility>
+
+#include <cm/memory>
+#include <cm/optional>
+#include <cm/string_view>
+#include <cmext/enum_set>
+#include <cmext/string_view>
+
+#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
+#include "cmExecutionStatus.h"
+#include "cmFunctionBlocker.h"
+#include "cmListFileCache.h"
+#include "cmMakefile.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+namespace {
+enum class ScopeType : std::uint8_t
+{
+ VARIABLES,
+ POLICIES
+};
+using ScopeSet = cm::enum_set<ScopeType>;
+
+class BlockScopePushPop
+{
+public:
+ BlockScopePushPop(cmMakefile* m, const ScopeSet& scopes);
+ ~BlockScopePushPop() = default;
+
+ BlockScopePushPop(const BlockScopePushPop&) = delete;
+ BlockScopePushPop& operator=(const BlockScopePushPop&) = delete;
+
+private:
+ std::unique_ptr<cmMakefile::PolicyPushPop> PolicyScope;
+ std::unique_ptr<cmMakefile::VariablePushPop> VariableScope;
+};
+
+BlockScopePushPop::BlockScopePushPop(cmMakefile* mf, const ScopeSet& scopes)
+{
+ if (scopes.contains(ScopeType::POLICIES)) {
+ this->PolicyScope = cm::make_unique<cmMakefile::PolicyPushPop>(mf);
+ }
+ if (scopes.contains(ScopeType::VARIABLES)) {
+ this->VariableScope = cm::make_unique<cmMakefile::VariablePushPop>(mf);
+ }
+}
+
+class cmBlockFunctionBlocker : public cmFunctionBlocker
+{
+public:
+ cmBlockFunctionBlocker(cmMakefile* mf, const ScopeSet& scopes,
+ std::vector<std::string> variableNames);
+ ~cmBlockFunctionBlocker() override;
+
+ cm::string_view StartCommandName() const override { return "block"_s; }
+ cm::string_view EndCommandName() const override { return "endblock"_s; }
+
+ bool EndCommandSupportsArguments() const override { return false; }
+
+ bool ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile& mf) const override;
+
+ bool Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus) override;
+
+private:
+ cmMakefile* Makefile;
+ ScopeSet Scopes;
+ BlockScopePushPop BlockScope;
+ std::vector<std::string> VariableNames;
+};
+
+cmBlockFunctionBlocker::cmBlockFunctionBlocker(
+ cmMakefile* const mf, const ScopeSet& scopes,
+ std::vector<std::string> variableNames)
+ : Makefile{ mf }
+ , Scopes{ scopes }
+ , BlockScope{ mf, scopes }
+ , VariableNames{ std::move(variableNames) }
+{
+}
+
+cmBlockFunctionBlocker::~cmBlockFunctionBlocker()
+{
+ if (this->Scopes.contains(ScopeType::VARIABLES)) {
+ this->Makefile->RaiseScope(this->VariableNames);
+ }
+}
+
+bool cmBlockFunctionBlocker::ArgumentsMatch(cmListFileFunction const& lff,
+ cmMakefile&) const
+{
+ // no arguments expected for endblock()
+ // but this method should not be called because EndCommandHasArguments()
+ // returns false.
+ return lff.Arguments().empty();
+}
+
+bool cmBlockFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
+ cmExecutionStatus& inStatus)
+{
+ auto& mf = inStatus.GetMakefile();
+
+ // Invoke all the functions that were collected in the block.
+ for (cmListFileFunction const& fn : functions) {
+ cmExecutionStatus status(mf);
+ mf.ExecuteCommand(fn, status);
+ if (status.GetReturnInvoked()) {
+ mf.RaiseScope(status.GetReturnVariables());
+ inStatus.SetReturnInvoked(status.GetReturnVariables());
+ return true;
+ }
+ if (status.GetBreakInvoked()) {
+ inStatus.SetBreakInvoked();
+ return true;
+ }
+ if (status.GetContinueInvoked()) {
+ inStatus.SetContinueInvoked();
+ return true;
+ }
+ if (cmSystemTools::GetFatalErrorOccurred()) {
+ return true;
+ }
+ }
+ return true;
+}
+
+} // anonymous namespace
+
+bool cmBlockCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ struct Arguments : public ArgumentParser::ParseResult
+ {
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> ScopeFor;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Propagate;
+ };
+ static auto const parser = cmArgumentParser<Arguments>{}
+ .Bind("SCOPE_FOR"_s, &Arguments::ScopeFor)
+ .Bind("PROPAGATE"_s, &Arguments::Propagate);
+ std::vector<std::string> unrecognizedArguments;
+ auto parsedArgs = parser.Parse(args, &unrecognizedArguments);
+
+ if (!unrecognizedArguments.empty()) {
+ status.SetError(cmStrCat("called with unsupported argument \"",
+ unrecognizedArguments[0], '"'));
+ cmSystemTools::SetFatalErrorOccurred();
+ return false;
+ }
+
+ if (parsedArgs.MaybeReportError(status.GetMakefile())) {
+ cmSystemTools::SetFatalErrorOccurred();
+ return true;
+ }
+
+ ScopeSet scopes;
+
+ if (parsedArgs.ScopeFor) {
+ for (auto const& scope : *parsedArgs.ScopeFor) {
+ if (scope == "VARIABLES"_s) {
+ scopes.insert(ScopeType::VARIABLES);
+ continue;
+ }
+ if (scope == "POLICIES"_s) {
+ scopes.insert(ScopeType::POLICIES);
+ continue;
+ }
+ status.SetError(cmStrCat("SCOPE_FOR unsupported scope \"", scope, '"'));
+ cmSystemTools::SetFatalErrorOccurred();
+ return false;
+ }
+ } else {
+ scopes = { ScopeType::VARIABLES, ScopeType::POLICIES };
+ }
+ if (!scopes.contains(ScopeType::VARIABLES) &&
+ !parsedArgs.Propagate.empty()) {
+ status.SetError(
+ "PROPAGATE cannot be specified without a new scope for VARIABLES");
+ cmSystemTools::SetFatalErrorOccurred();
+ return false;
+ }
+
+ // create a function blocker
+ auto fb = cm::make_unique<cmBlockFunctionBlocker>(
+ &status.GetMakefile(), scopes, parsedArgs.Propagate);
+ status.GetMakefile().AddFunctionBlocker(std::move(fb));
+
+ return true;
+}
diff --git a/Source/cmBlockCommand.h b/Source/cmBlockCommand.h
new file mode 100644
index 0000000..5fd8f42
--- /dev/null
+++ b/Source/cmBlockCommand.h
@@ -0,0 +1,14 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <string>
+#include <vector>
+
+class cmExecutionStatus;
+
+/// Starts block() ... endblock() block
+bool cmBlockCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
diff --git a/Source/cmCMakeHostSystemInformationCommand.cxx b/Source/cmCMakeHostSystemInformationCommand.cxx
index 0750eea..58129a0 100644
--- a/Source/cmCMakeHostSystemInformationCommand.cxx
+++ b/Source/cmCMakeHostSystemInformationCommand.cxx
@@ -474,7 +474,7 @@ bool QueryWindowsRegistry(Range args, cmExecutionStatus& status,
}
std::string const& key = *args.begin();
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
std::string ValueName;
bool ValueNames = false;
@@ -491,19 +491,15 @@ bool QueryWindowsRegistry(Range args, cmExecutionStatus& status,
.Bind("SEPARATOR"_s, &Arguments::Separator)
.Bind("ERROR_VARIABLE"_s, &Arguments::ErrorVariable);
std::vector<std::string> invalidArgs;
- std::vector<std::string> keywordsMissingValue;
- Arguments const arguments =
- parser.Parse(args.advance(1), &invalidArgs, &keywordsMissingValue);
+ Arguments const arguments = parser.Parse(args.advance(1), &invalidArgs);
if (!invalidArgs.empty()) {
status.SetError(cmStrCat("given invalid argument(s) \"",
cmJoin(invalidArgs, ", "_s), "\"."));
return false;
}
- if (!keywordsMissingValue.empty()) {
- status.SetError(cmStrCat("missing expected value for argument(s) \"",
- cmJoin(keywordsMissingValue, ", "_s), "\"."));
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if ((!arguments.ValueName.empty() &&
(arguments.ValueNames || arguments.SubKeys)) ||
diff --git a/Source/cmCMakeLanguageCommand.cxx b/Source/cmCMakeLanguageCommand.cxx
index a2aaa2a..68e658c 100644
--- a/Source/cmCMakeLanguageCommand.cxx
+++ b/Source/cmCMakeLanguageCommand.cxx
@@ -14,15 +14,18 @@
#include <cmext/string_view>
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
#include "cmDependencyProvider.h"
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmRange.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmake.h"
namespace {
@@ -33,13 +36,14 @@ bool FatalError(cmExecutionStatus& status, std::string const& error)
return false;
}
-std::array<cm::static_string_view, 12> InvalidCommands{
+std::array<cm::static_string_view, 14> InvalidCommands{
{ // clang-format off
"function"_s, "endfunction"_s,
"macro"_s, "endmacro"_s,
"if"_s, "elseif"_s, "else"_s, "endif"_s,
"while"_s, "endwhile"_s,
- "foreach"_s, "endforeach"_s
+ "foreach"_s, "endforeach"_s,
+ "block"_s, "endblock"_s
} // clang-format on
};
@@ -235,7 +239,7 @@ bool cmCMakeLanguageCommandSET_DEPENDENCY_PROVIDER(
struct SetProviderArgs
{
std::string Command;
- std::vector<std::string> Methods;
+ ArgumentParser::NonEmpty<std::vector<std::string>> Methods;
};
auto const ArgsParser =
@@ -303,6 +307,27 @@ bool cmCMakeLanguageCommandSET_DEPENDENCY_PROVIDER(
return true;
}
+
+bool cmCMakeLanguageCommandGET_MESSAGE_LOG_LEVEL(
+ std::vector<cmListFileArgument> const& args, cmExecutionStatus& status)
+{
+ cmMakefile& makefile = status.GetMakefile();
+ std::vector<std::string> expandedArgs;
+ makefile.ExpandArguments(args, expandedArgs);
+
+ if (args.size() < 2 || expandedArgs.size() > 2) {
+ return FatalError(
+ status,
+ "sub-command GET_MESSAGE_LOG_LEVEL expects exactly one argument");
+ }
+
+ Message::LogLevel logLevel = makefile.GetCurrentLogLevel();
+ std::string outputValue = cmake::LogLevelToString(logLevel);
+
+ const std::string& outputVariable = expandedArgs[1];
+ makefile.AddDefinition(outputVariable, outputValue);
+ return true;
+}
}
bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
@@ -451,5 +476,9 @@ bool cmCMakeLanguageCommand(std::vector<cmListFileArgument> const& args,
return cmCMakeLanguageCommandEVAL(args, status);
}
+ if (expArgs[expArg] == "GET_MESSAGE_LOG_LEVEL") {
+ return cmCMakeLanguageCommandGET_MESSAGE_LOG_LEVEL(args, status);
+ }
+
return FatalError(status, "called with unknown meta-operation");
}
diff --git a/Source/cmCMakePathCommand.cxx b/Source/cmCMakePathCommand.cxx
index bf94c2d..7755082 100644
--- a/Source/cmCMakePathCommand.cxx
+++ b/Source/cmCMakePathCommand.cxx
@@ -2,7 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCMakePathCommand.h"
-#include <algorithm>
#include <functional>
#include <iomanip>
#include <map>
@@ -11,10 +10,12 @@
#include <utility>
#include <vector>
+#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
#include "cmCMakePath.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
@@ -43,15 +44,12 @@ public:
}
template <int Advance = 2>
- Result Parse(std::vector<std::string> const& args,
- std::vector<std::string>* keywordsMissingValue = nullptr,
- std::vector<std::string>* parsedKeywords = nullptr) const
+ Result Parse(std::vector<std::string> const& args) const
{
this->Inputs.clear();
return this->cmArgumentParser<Result>::Parse(
- cmMakeRange(args).advance(Advance), &this->Inputs, keywordsMissingValue,
- parsedKeywords);
+ cmMakeRange(args).advance(Advance), &this->Inputs);
}
const std::vector<std::string>& GetInputs() const { return this->Inputs; }
@@ -82,52 +80,14 @@ public:
template <int Advance = 2>
Result Parse(std::vector<std::string> const& args) const
{
- this->KeywordsMissingValue.clear();
- this->ParsedKeywords.clear();
-
return this->CMakePathArgumentParser<Result>::template Parse<Advance>(
- args, &this->KeywordsMissingValue, &this->ParsedKeywords);
- }
-
- const std::vector<std::string>& GetKeywordsMissingValue() const
- {
- return this->KeywordsMissingValue;
- }
- const std::vector<std::string>& GetParsedKeywords() const
- {
- return this->ParsedKeywords;
- }
-
- bool checkOutputVariable(const Result& arguments,
- cmExecutionStatus& status) const
- {
- if (std::find(this->GetKeywordsMissingValue().begin(),
- this->GetKeywordsMissingValue().end(),
- "OUTPUT_VARIABLE"_s) !=
- this->GetKeywordsMissingValue().end()) {
- status.SetError("OUTPUT_VARIABLE requires an argument.");
- return false;
- }
-
- if (std::find(this->GetParsedKeywords().begin(),
- this->GetParsedKeywords().end(),
- "OUTPUT_VARIABLE"_s) != this->GetParsedKeywords().end() &&
- arguments.Output.empty()) {
- status.SetError("Invalid name for output variable.");
- return false;
- }
-
- return true;
+ args);
}
-
-private:
- mutable std::vector<std::string> KeywordsMissingValue;
- mutable std::vector<std::string> ParsedKeywords;
};
-struct OutputVariable
+struct OutputVariable : public ArgumentParser::ParseResult
{
- std::string Output;
+ cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
};
// Usable when OUTPUT_VARIABLE is the only option
class OutputVariableParser
@@ -297,8 +257,8 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
cmCMakePath path(status.GetMakefile().GetSafeDefinition(args[1]));
@@ -307,7 +267,7 @@ bool HandleAppendCommand(std::vector<std::string> const& args,
}
status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
+ arguments.Output ? *arguments.Output : args[1], path.String());
return true;
}
@@ -319,8 +279,8 @@ bool HandleAppendStringCommand(std::vector<std::string> const& args,
const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
std::string inputPath;
@@ -334,7 +294,7 @@ bool HandleAppendStringCommand(std::vector<std::string> const& args,
}
status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
+ arguments.Output ? *arguments.Output : args[1], path.String());
return true;
}
@@ -346,8 +306,8 @@ bool HandleRemoveFilenameCommand(std::vector<std::string> const& args,
const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (!parser.GetInputs().empty()) {
@@ -364,7 +324,7 @@ bool HandleRemoveFilenameCommand(std::vector<std::string> const& args,
path.RemoveFileName();
status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
+ arguments.Output ? *arguments.Output : args[1], path.String());
return true;
}
@@ -376,8 +336,8 @@ bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (parser.GetInputs().size() > 1) {
@@ -395,7 +355,7 @@ bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
parser.GetInputs().empty() ? "" : parser.GetInputs().front());
status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
+ arguments.Output ? *arguments.Output : args[1], path.String());
return true;
}
@@ -403,9 +363,9 @@ bool HandleReplaceFilenameCommand(std::vector<std::string> const& args,
bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
- std::string Output;
+ cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
bool LastOnly = false;
};
@@ -415,8 +375,8 @@ bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
Arguments const arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (!parser.GetInputs().empty()) {
@@ -438,7 +398,7 @@ bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
}
status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
+ arguments.Output ? *arguments.Output : args[1], path.String());
return true;
}
@@ -446,9 +406,9 @@ bool HandleRemoveExtensionCommand(std::vector<std::string> const& args,
bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
- std::string Output;
+ cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
bool LastOnly = false;
};
@@ -458,8 +418,8 @@ bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
Arguments const arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (parser.GetInputs().size() > 1) {
@@ -483,7 +443,7 @@ bool HandleReplaceExtensionCommand(std::vector<std::string> const& args,
}
status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
+ arguments.Output ? *arguments.Output : args[1], path.String());
return true;
}
@@ -495,8 +455,8 @@ bool HandleNormalPathCommand(std::vector<std::string> const& args,
const auto arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (!parser.GetInputs().empty()) {
@@ -512,7 +472,7 @@ bool HandleNormalPathCommand(std::vector<std::string> const& args,
auto path = cmCMakePath(inputPath).Normal();
status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
+ arguments.Output ? *arguments.Output : args[1], path.String());
return true;
}
@@ -523,10 +483,10 @@ bool HandleTransformPathCommand(
const std::string& base)>& transform,
bool normalizeOption = false)
{
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
- std::string Output;
- std::string BaseDirectory;
+ cm::optional<ArgumentParser::NonEmpty<std::string>> Output;
+ cm::optional<std::string> BaseDirectory;
bool Normalize = false;
};
@@ -538,8 +498,8 @@ bool HandleTransformPathCommand(
Arguments arguments = parser.Parse(args);
- if (!parser.checkOutputVariable(arguments, status)) {
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (!parser.GetInputs().empty()) {
@@ -547,17 +507,11 @@ bool HandleTransformPathCommand(
return false;
}
- if (std::find(parser.GetKeywordsMissingValue().begin(),
- parser.GetKeywordsMissingValue().end(), "BASE_DIRECTORY"_s) !=
- parser.GetKeywordsMissingValue().end()) {
- status.SetError("BASE_DIRECTORY requires an argument.");
- return false;
- }
-
- if (std::find(parser.GetParsedKeywords().begin(),
- parser.GetParsedKeywords().end(),
- "BASE_DIRECTORY"_s) == parser.GetParsedKeywords().end()) {
- arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
+ std::string baseDirectory;
+ if (arguments.BaseDirectory) {
+ baseDirectory = *arguments.BaseDirectory;
+ } else {
+ baseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
}
std::string inputPath;
@@ -565,13 +519,13 @@ bool HandleTransformPathCommand(
return false;
}
- auto path = transform(cmCMakePath(inputPath), arguments.BaseDirectory);
+ auto path = transform(cmCMakePath(inputPath), baseDirectory);
if (arguments.Normalize) {
path = path.Normal();
}
status.GetMakefile().AddDefinition(
- arguments.Output.empty() ? args[1] : arguments.Output, path.String());
+ arguments.Output ? *arguments.Output : args[1], path.String());
return true;
}
diff --git a/Source/cmCMakePresetsGraph.cxx b/Source/cmCMakePresetsGraph.cxx
index b737c1f..c168a45 100644
--- a/Source/cmCMakePresetsGraph.cxx
+++ b/Source/cmCMakePresetsGraph.cxx
@@ -43,6 +43,7 @@ using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
using ConfigurePreset = cmCMakePresetsGraph::ConfigurePreset;
using BuildPreset = cmCMakePresetsGraph::BuildPreset;
using TestPreset = cmCMakePresetsGraph::TestPreset;
+using PackagePreset = cmCMakePresetsGraph::PackagePreset;
using ExpandMacroResult = cmCMakePresetsGraphInternal::ExpandMacroResult;
using MacroExpander = cmCMakePresetsGraphInternal::MacroExpander;
@@ -301,6 +302,28 @@ bool ExpandMacros(const cmCMakePresetsGraph& graph, const TestPreset& preset,
return true;
}
+bool ExpandMacros(const cmCMakePresetsGraph& graph,
+ const PackagePreset& preset,
+ cm::optional<PackagePreset>& out,
+ const std::vector<MacroExpander>& macroExpanders)
+{
+ for (auto& variable : out->Variables) {
+ CHECK_EXPAND(out, variable.second, macroExpanders,
+ graph.GetVersion(preset));
+ }
+
+ CHECK_EXPAND(out, out->ConfigFile, macroExpanders, graph.GetVersion(preset));
+ CHECK_EXPAND(out, out->PackageName, macroExpanders,
+ graph.GetVersion(preset));
+ CHECK_EXPAND(out, out->PackageVersion, macroExpanders,
+ graph.GetVersion(preset));
+ CHECK_EXPAND(out, out->PackageDirectory, macroExpanders,
+ graph.GetVersion(preset));
+ CHECK_EXPAND(out, out->VendorName, macroExpanders, graph.GetVersion(preset));
+
+ return true;
+}
+
template <class T>
bool ExpandMacros(const cmCMakePresetsGraph& graph, const T& preset,
cm::optional<T>& out)
@@ -868,6 +891,44 @@ cmCMakePresetsGraph::TestPreset::VisitPresetAfterInherit(int /* version */)
return ReadFileResult::READ_OK;
}
+cmCMakePresetsGraph::ReadFileResult
+cmCMakePresetsGraph::PackagePreset::VisitPresetInherit(
+ const cmCMakePresetsGraph::Preset& parentPreset)
+{
+ auto& preset = *this;
+ const PackagePreset& parent =
+ static_cast<const PackagePreset&>(parentPreset);
+
+ InheritString(preset.ConfigurePreset, parent.ConfigurePreset);
+ InheritOptionalValue(preset.InheritConfigureEnvironment,
+ parent.InheritConfigureEnvironment);
+ InheritVector(preset.Generators, parent.Generators);
+ InheritVector(preset.Configurations, parent.Configurations);
+
+ for (auto const& v : parent.Variables) {
+ preset.Variables.insert(v);
+ }
+
+ InheritOptionalValue(preset.DebugOutput, parent.DebugOutput);
+ InheritOptionalValue(preset.VerboseOutput, parent.VerboseOutput);
+ InheritString(preset.PackageName, parent.PackageName);
+ InheritString(preset.PackageVersion, parent.PackageVersion);
+ InheritString(preset.PackageDirectory, parent.PackageDirectory);
+ InheritString(preset.VendorName, parent.VendorName);
+
+ return ReadFileResult::READ_OK;
+}
+
+cmCMakePresetsGraph::ReadFileResult
+cmCMakePresetsGraph::PackagePreset::VisitPresetAfterInherit(int /* version */)
+{
+ auto& preset = *this;
+ if (!preset.Hidden && preset.ConfigurePreset.empty()) {
+ return ReadFileResult::INVALID_PRESET;
+ }
+ return ReadFileResult::READ_OK;
+}
+
std::string cmCMakePresetsGraph::GetFilename(const std::string& sourceDir)
{
return cmStrCat(sourceDir, "/CMakePresets.json");
@@ -901,8 +962,9 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
std::string filename = GetUserFilename(this->SourceDir);
std::vector<File*> inProgressFiles;
if (cmSystemTools::FileExists(filename)) {
- auto result = this->ReadJSONFile(filename, RootType::User,
- ReadReason::Root, inProgressFiles, file);
+ auto result =
+ this->ReadJSONFile(filename, RootType::User, ReadReason::Root,
+ inProgressFiles, file, this->errors);
if (result != ReadFileResult::READ_OK) {
return result;
}
@@ -910,8 +972,9 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
} else {
filename = GetFilename(this->SourceDir);
if (cmSystemTools::FileExists(filename)) {
- auto result = this->ReadJSONFile(
- filename, RootType::Project, ReadReason::Root, inProgressFiles, file);
+ auto result =
+ this->ReadJSONFile(filename, RootType::Project, ReadReason::Root,
+ inProgressFiles, file, this->errors);
if (result != ReadFileResult::READ_OK) {
return result;
}
@@ -928,6 +991,7 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
CHECK_OK(ComputePresetInheritance(this->ConfigurePresets, *this));
CHECK_OK(ComputePresetInheritance(this->BuildPresets, *this));
CHECK_OK(ComputePresetInheritance(this->TestPresets, *this));
+ CHECK_OK(ComputePresetInheritance(this->PackagePresets, *this));
for (auto& it : this->ConfigurePresets) {
if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
@@ -983,6 +1047,30 @@ cmCMakePresetsGraph::ReadProjectPresetsInternal(bool allowNoFiles)
}
}
+ for (auto& it : this->PackagePresets) {
+ if (!it.second.Unexpanded.Hidden) {
+ const auto configurePreset =
+ this->ConfigurePresets.find(it.second.Unexpanded.ConfigurePreset);
+ if (configurePreset == this->ConfigurePresets.end()) {
+ return ReadFileResult::INVALID_CONFIGURE_PRESET;
+ }
+ if (!it.second.Unexpanded.OriginFile->ReachableFiles.count(
+ configurePreset->second.Unexpanded.OriginFile)) {
+ return ReadFileResult::CONFIGURE_PRESET_UNREACHABLE_FROM_FILE;
+ }
+
+ if (it.second.Unexpanded.InheritConfigureEnvironment.value_or(true)) {
+ it.second.Unexpanded.Environment.insert(
+ configurePreset->second.Unexpanded.Environment.begin(),
+ configurePreset->second.Unexpanded.Environment.end());
+ }
+ }
+
+ if (!ExpandMacros(*this, it.second.Unexpanded, it.second.Expanded)) {
+ return ReadFileResult::INVALID_MACRO_EXPANSION;
+ }
+ }
+
return ReadFileResult::READ_OK;
}
@@ -1026,6 +1114,8 @@ const char* cmCMakePresetsGraph::ResultToString(ReadFileResult result)
case ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED:
return "File version must be 2 or higher for build and test preset "
"support.";
+ case ReadFileResult::PACKAGE_PRESETS_UNSUPPORTED:
+ return "File version must be 5 or higher for package preset support";
case ReadFileResult::INCLUDE_UNSUPPORTED:
return "File version must be 4 or higher for include support";
case ReadFileResult::INVALID_INCLUDE:
@@ -1065,6 +1155,16 @@ void cmCMakePresetsGraph::ClearPresets()
this->Files.clear();
}
+void cmCMakePresetsGraph::printPrecedingNewline(PrintPrecedingNewline* newline)
+{
+ if (newline) {
+ if (*newline == PrintPrecedingNewline::True) {
+ std::cout << std::endl;
+ }
+ *newline = PrintPrecedingNewline::True;
+ }
+}
+
void cmCMakePresetsGraph::PrintPresets(
const std::vector<const cmCMakePresetsGraph::Preset*>& presets)
{
@@ -1093,13 +1193,16 @@ void cmCMakePresetsGraph::PrintPresets(
}
}
-void cmCMakePresetsGraph::PrintConfigurePresetList() const
+void cmCMakePresetsGraph::PrintConfigurePresetList(
+ PrintPrecedingNewline* newline) const
{
- PrintConfigurePresetList([](const ConfigurePreset&) { return true; });
+ PrintConfigurePresetList([](const ConfigurePreset&) { return true; },
+ newline);
}
void cmCMakePresetsGraph::PrintConfigurePresetList(
- const std::function<bool(const ConfigurePreset&)>& filter) const
+ const std::function<bool(const ConfigurePreset&)>& filter,
+ PrintPrecedingNewline* newline) const
{
std::vector<const cmCMakePresetsGraph::Preset*> presets;
for (auto const& p : this->ConfigurePresetOrder) {
@@ -1112,12 +1215,14 @@ void cmCMakePresetsGraph::PrintConfigurePresetList(
}
if (!presets.empty()) {
+ printPrecedingNewline(newline);
std::cout << "Available configure presets:\n\n";
cmCMakePresetsGraph::PrintPresets(presets);
}
}
-void cmCMakePresetsGraph::PrintBuildPresetList() const
+void cmCMakePresetsGraph::PrintBuildPresetList(
+ PrintPrecedingNewline* newline) const
{
std::vector<const cmCMakePresetsGraph::Preset*> presets;
for (auto const& p : this->BuildPresetOrder) {
@@ -1130,12 +1235,14 @@ void cmCMakePresetsGraph::PrintBuildPresetList() const
}
if (!presets.empty()) {
+ printPrecedingNewline(newline);
std::cout << "Available build presets:\n\n";
cmCMakePresetsGraph::PrintPresets(presets);
}
}
-void cmCMakePresetsGraph::PrintTestPresetList() const
+void cmCMakePresetsGraph::PrintTestPresetList(
+ PrintPrecedingNewline* newline) const
{
std::vector<const cmCMakePresetsGraph::Preset*> presets;
for (auto const& p : this->TestPresetOrder) {
@@ -1148,16 +1255,45 @@ void cmCMakePresetsGraph::PrintTestPresetList() const
}
if (!presets.empty()) {
+ printPrecedingNewline(newline);
std::cout << "Available test presets:\n\n";
cmCMakePresetsGraph::PrintPresets(presets);
}
}
+void cmCMakePresetsGraph::PrintPackagePresetList(
+ PrintPrecedingNewline* newline) const
+{
+ this->PrintPackagePresetList([](const PackagePreset&) { return true; },
+ newline);
+}
+
+void cmCMakePresetsGraph::PrintPackagePresetList(
+ const std::function<bool(const PackagePreset&)>& filter,
+ PrintPrecedingNewline* newline) const
+{
+ std::vector<const cmCMakePresetsGraph::Preset*> presets;
+ for (auto const& p : this->PackagePresetOrder) {
+ auto const& preset = this->PackagePresets.at(p);
+ if (!preset.Unexpanded.Hidden && preset.Expanded &&
+ preset.Expanded->ConditionResult && filter(preset.Unexpanded)) {
+ presets.push_back(
+ static_cast<const cmCMakePresetsGraph::Preset*>(&preset.Unexpanded));
+ }
+ }
+
+ if (!presets.empty()) {
+ printPrecedingNewline(newline);
+ std::cout << "Available package presets:\n\n";
+ cmCMakePresetsGraph::PrintPresets(presets);
+ }
+}
+
void cmCMakePresetsGraph::PrintAllPresets() const
{
- this->PrintConfigurePresetList();
- std::cout << std::endl;
- this->PrintBuildPresetList();
- std::cout << std::endl;
- this->PrintTestPresetList();
+ PrintPrecedingNewline newline = PrintPrecedingNewline::False;
+ this->PrintConfigurePresetList(&newline);
+ this->PrintBuildPresetList(&newline);
+ this->PrintTestPresetList(&newline);
+ this->PrintPackagePresetList(&newline);
}
diff --git a/Source/cmCMakePresetsGraph.h b/Source/cmCMakePresetsGraph.h
index f1f8662..806a36d 100644
--- a/Source/cmCMakePresetsGraph.h
+++ b/Source/cmCMakePresetsGraph.h
@@ -41,6 +41,7 @@ public:
CONFIGURE_PRESET_UNREACHABLE_FROM_FILE,
INVALID_MACRO_EXPANSION,
BUILD_TEST_PRESETS_UNSUPPORTED,
+ PACKAGE_PRESETS_UNSUPPORTED,
INCLUDE_UNSUPPORTED,
INVALID_INCLUDE,
INVALID_CONFIGURE_PRESET,
@@ -52,6 +53,7 @@ public:
TEST_OUTPUT_TRUNCATION_UNSUPPORTED,
};
+ std::string errors;
enum class ArchToolsetStrategy
{
Set,
@@ -325,6 +327,42 @@ public:
ReadFileResult VisitPresetAfterInherit(int /* version */) override;
};
+ class PackagePreset : public Preset
+ {
+ public:
+ PackagePreset() = default;
+ PackagePreset(PackagePreset&& /*other*/) = default;
+ PackagePreset(const PackagePreset& /*other*/) = default;
+ PackagePreset& operator=(const PackagePreset& /*other*/) = default;
+ ~PackagePreset() override = default;
+#if __cplusplus >= 201703L || (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
+ PackagePreset& operator=(PackagePreset&& /*other*/) = default;
+#else
+ // The move assignment operators for several STL classes did not become
+ // noexcept until C++17, which causes some tools to warn about this move
+ // assignment operator throwing an exception when it shouldn't.
+ PackagePreset& operator=(PackagePreset&& /*other*/) = delete;
+#endif
+
+ std::string ConfigurePreset;
+ cm::optional<bool> InheritConfigureEnvironment;
+ std::vector<std::string> Generators;
+ std::vector<std::string> Configurations;
+ std::map<std::string, std::string> Variables;
+ std::string ConfigFile;
+
+ cm::optional<bool> DebugOutput;
+ cm::optional<bool> VerboseOutput;
+
+ std::string PackageName;
+ std::string PackageVersion;
+ std::string PackageDirectory;
+ std::string VendorName;
+
+ ReadFileResult VisitPresetInherit(const Preset& parent) override;
+ ReadFileResult VisitPresetAfterInherit(int /* version */) override;
+ };
+
template <class T>
class PresetPair
{
@@ -336,10 +374,12 @@ public:
std::map<std::string, PresetPair<ConfigurePreset>> ConfigurePresets;
std::map<std::string, PresetPair<BuildPreset>> BuildPresets;
std::map<std::string, PresetPair<TestPreset>> TestPresets;
+ std::map<std::string, PresetPair<PackagePreset>> PackagePresets;
std::vector<std::string> ConfigurePresetOrder;
std::vector<std::string> BuildPresetOrder;
std::vector<std::string> TestPresetOrder;
+ std::vector<std::string> PackagePresetOrder;
std::string SourceDir;
std::vector<std::unique_ptr<File>> Files;
@@ -382,13 +422,26 @@ public:
return "";
}
+ enum class PrintPrecedingNewline
+ {
+ False,
+ True,
+ };
+ static void printPrecedingNewline(PrintPrecedingNewline* p);
+
static void PrintPresets(
const std::vector<const cmCMakePresetsGraph::Preset*>& presets);
- void PrintConfigurePresetList() const;
void PrintConfigurePresetList(
- const std::function<bool(const ConfigurePreset&)>& filter) const;
- void PrintBuildPresetList() const;
- void PrintTestPresetList() const;
+ PrintPrecedingNewline* newline = nullptr) const;
+ void PrintConfigurePresetList(
+ const std::function<bool(const ConfigurePreset&)>& filter,
+ PrintPrecedingNewline* newline = nullptr) const;
+ void PrintBuildPresetList(PrintPrecedingNewline* newline = nullptr) const;
+ void PrintTestPresetList(PrintPrecedingNewline* newline = nullptr) const;
+ void PrintPackagePresetList(PrintPrecedingNewline* newline = nullptr) const;
+ void PrintPackagePresetList(
+ const std::function<bool(const PackagePreset&)>& filter,
+ PrintPrecedingNewline* newline = nullptr) const;
void PrintAllPresets() const;
private:
@@ -407,7 +460,7 @@ private:
ReadFileResult ReadProjectPresetsInternal(bool allowNoFiles);
ReadFileResult ReadJSONFile(const std::string& filename, RootType rootType,
ReadReason readReason,
- std::vector<File*>& inProgressFiles,
- File*& file);
+ std::vector<File*>& inProgressFiles, File*& file,
+ std::string& errMsg);
void ClearPresets();
};
diff --git a/Source/cmCMakePresetsGraphInternal.h b/Source/cmCMakePresetsGraphInternal.h
index f7c7349..40af356 100644
--- a/Source/cmCMakePresetsGraphInternal.h
+++ b/Source/cmCMakePresetsGraphInternal.h
@@ -147,6 +147,10 @@ cmCMakePresetsGraph::ReadFileResult BuildPresetsHelper(
cmCMakePresetsGraph::ReadFileResult TestPresetsHelper(
std::vector<cmCMakePresetsGraph::TestPreset>& out, const Json::Value* value);
+cmCMakePresetsGraph::ReadFileResult PackagePresetsHelper(
+ std::vector<cmCMakePresetsGraph::PackagePreset>& out,
+ const Json::Value* value);
+
cmJSONHelper<std::nullptr_t, cmCMakePresetsGraph::ReadFileResult> VendorHelper(
cmCMakePresetsGraph::ReadFileResult error);
diff --git a/Source/cmCMakePresetsGraphReadJSON.cxx b/Source/cmCMakePresetsGraphReadJSON.cxx
index d11e839..4fba7d9 100644
--- a/Source/cmCMakePresetsGraphReadJSON.cxx
+++ b/Source/cmCMakePresetsGraphReadJSON.cxx
@@ -34,7 +34,7 @@ using ArchToolsetStrategy = cmCMakePresetsGraph::ArchToolsetStrategy;
using JSONHelperBuilder = cmJSONHelperBuilder<ReadFileResult>;
constexpr int MIN_VERSION = 1;
-constexpr int MAX_VERSION = 5;
+constexpr int MAX_VERSION = 6;
struct CMakeVersion
{
@@ -49,6 +49,7 @@ struct RootPresets
std::vector<cmCMakePresetsGraph::ConfigurePreset> ConfigurePresets;
std::vector<cmCMakePresetsGraph::BuildPreset> BuildPresets;
std::vector<cmCMakePresetsGraph::TestPreset> TestPresets;
+ std::vector<cmCMakePresetsGraph::PackagePreset> PackagePresets;
std::vector<std::string> Include;
};
@@ -281,6 +282,8 @@ auto const RootPresetsHelper =
cmCMakePresetsGraphInternal::BuildPresetsHelper, false)
.Bind("testPresets"_s, &RootPresets::TestPresets,
cmCMakePresetsGraphInternal::TestPresetsHelper, false)
+ .Bind("packagePresets"_s, &RootPresets::PackagePresets,
+ cmCMakePresetsGraphInternal::PackagePresetsHelper, false)
.Bind("cmakeMinimumRequired"_s, &RootPresets::CMakeMinimumRequired,
CMakeVersionHelper, false)
.Bind("include"_s, &RootPresets::Include, IncludeVectorHelper, false)
@@ -411,7 +414,7 @@ cmCMakePresetsGraph::ReadFileResult EnvironmentMapHelper(
cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
const std::string& filename, RootType rootType, ReadReason readReason,
- std::vector<File*>& inProgressFiles, File*& file)
+ std::vector<File*>& inProgressFiles, File*& file, std::string& errMsg)
{
ReadFileResult result;
@@ -430,6 +433,7 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
cmsys::ifstream fin(filename.c_str());
if (!fin) {
+ errMsg = cmStrCat(filename, ": Failed to read file\n", errMsg);
return ReadFileResult::FILE_NOT_FOUND;
}
// If there's a BOM, toss it.
@@ -438,7 +442,8 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
Json::Value root;
Json::CharReaderBuilder builder;
Json::CharReaderBuilder::strictMode(&builder.settings_);
- if (!Json::parseFromStream(builder, fin, &root, nullptr)) {
+ if (!Json::parseFromStream(builder, fin, &root, &errMsg)) {
+ errMsg = cmStrCat(filename, ":\n", errMsg);
return ReadFileResult::JSON_PARSE_ERROR;
}
@@ -456,6 +461,11 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
return ReadFileResult::BUILD_TEST_PRESETS_UNSUPPORTED;
}
+ // Support for package presets added in version 6.
+ if (v < 6 && root.isMember("packagePresets")) {
+ return ReadFileResult::PACKAGE_PRESETS_UNSUPPORTED;
+ }
+
// Support for include added in version 4.
if (v < 4 && root.isMember("include")) {
return ReadFileResult::INCLUDE_UNSUPPORTED;
@@ -490,6 +500,8 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
for (auto& preset : presets.ConfigurePresets) {
preset.OriginFile = file;
if (preset.Name.empty()) {
+ errMsg += R"(\n\t)";
+ errMsg += filename;
return ReadFileResult::INVALID_PRESET;
}
@@ -523,6 +535,8 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
for (auto& preset : presets.BuildPresets) {
preset.OriginFile = file;
if (preset.Name.empty()) {
+ errMsg += R"(\n\t)";
+ errMsg += filename;
return ReadFileResult::INVALID_PRESET;
}
@@ -567,14 +581,34 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
this->TestPresetOrder.push_back(preset.Name);
}
+ for (auto& preset : presets.PackagePresets) {
+ preset.OriginFile = file;
+ if (preset.Name.empty()) {
+ return ReadFileResult::INVALID_PRESET;
+ }
+
+ PresetPair<PackagePreset> presetPair;
+ presetPair.Unexpanded = preset;
+ presetPair.Expanded = cm::nullopt;
+ if (!this->PackagePresets.emplace(preset.Name, presetPair).second) {
+ return ReadFileResult::DUPLICATE_PRESETS;
+ }
+
+ // Support for conditions added in version 3, but this requires version 5
+ // already, so no action needed.
+
+ this->PackagePresetOrder.push_back(preset.Name);
+ }
+
auto const includeFile = [this, &inProgressFiles, file](
const std::string& include, RootType rootType2,
- ReadReason readReason2) -> ReadFileResult {
+ ReadReason readReason2,
+ std::string& FailureMessage) -> ReadFileResult {
ReadFileResult r;
File* includedFile;
if ((r = this->ReadJSONFile(include, rootType2, readReason2,
- inProgressFiles, includedFile)) !=
- ReadFileResult::READ_OK) {
+ inProgressFiles, includedFile,
+ FailureMessage)) != ReadFileResult::READ_OK) {
return r;
}
@@ -589,8 +623,8 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
include = cmStrCat(directory, '/', include);
}
- if ((result = includeFile(include, rootType, ReadReason::Included)) !=
- ReadFileResult::READ_OK) {
+ if ((result = includeFile(include, rootType, ReadReason::Included,
+ errMsg)) != ReadFileResult::READ_OK) {
return result;
}
}
@@ -599,7 +633,7 @@ cmCMakePresetsGraph::ReadFileResult cmCMakePresetsGraph::ReadJSONFile(
auto cmakePresetsFilename = GetFilename(this->SourceDir);
if (cmSystemTools::FileExists(cmakePresetsFilename)) {
if ((result = includeFile(cmakePresetsFilename, RootType::Project,
- ReadReason::Root)) !=
+ ReadReason::Root, errMsg)) !=
ReadFileResult::READ_OK) {
return result;
}
diff --git a/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx b/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
new file mode 100644
index 0000000..4ae51b1
--- /dev/null
+++ b/Source/cmCMakePresetsGraphReadJSONPackagePresets.cxx
@@ -0,0 +1,95 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include <cstddef>
+#include <functional>
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+#include <cmext/string_view>
+
+#include <cm3p/json/value.h>
+
+#include "cmCMakePresetsGraph.h"
+#include "cmCMakePresetsGraphInternal.h"
+#include "cmJSONHelpers.h"
+
+namespace {
+using ReadFileResult = cmCMakePresetsGraph::ReadFileResult;
+using PackagePreset = cmCMakePresetsGraph::PackagePreset;
+
+auto const OutputHelper =
+ cmJSONHelperBuilder<ReadFileResult>::Object<PackagePreset>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ .Bind("debug"_s, &PackagePreset::DebugOutput,
+ cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
+ .Bind("verbose"_s, &PackagePreset::VerboseOutput,
+ cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false);
+
+auto const VariableHelper = cmJSONHelperBuilder<ReadFileResult>::String(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_VARIABLE);
+
+auto const VariablesHelper =
+ cmJSONHelperBuilder<ReadFileResult>::Map<std::string>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, VariableHelper);
+
+auto const PackagePresetHelper =
+ cmJSONHelperBuilder<ReadFileResult>::Object<PackagePreset>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESET, false)
+ .Bind("name"_s, &PackagePreset::Name,
+ cmCMakePresetsGraphInternal::PresetStringHelper)
+ .Bind("inherits"_s, &PackagePreset::Inherits,
+ cmCMakePresetsGraphInternal::PresetVectorOneOrMoreStringHelper,
+ false)
+ .Bind("hidden"_s, &PackagePreset::Hidden,
+ cmCMakePresetsGraphInternal::PresetBoolHelper, false)
+ .Bind<std::nullptr_t>("vendor"_s, nullptr,
+ cmCMakePresetsGraphInternal::VendorHelper(
+ ReadFileResult::INVALID_PRESET),
+ false)
+ .Bind("displayName"_s, &PackagePreset::DisplayName,
+ cmCMakePresetsGraphInternal::PresetStringHelper, false)
+ .Bind("description"_s, &PackagePreset::Description,
+ cmCMakePresetsGraphInternal::PresetStringHelper, false)
+ .Bind("environment"_s, &PackagePreset::Environment,
+ cmCMakePresetsGraphInternal::EnvironmentMapHelper, false)
+ .Bind("configurePreset"_s, &PackagePreset::ConfigurePreset,
+ cmCMakePresetsGraphInternal::PresetStringHelper, false)
+ .Bind("inheritConfigureEnvironment"_s,
+ &PackagePreset::InheritConfigureEnvironment,
+ cmCMakePresetsGraphInternal::PresetOptionalBoolHelper, false)
+ .Bind("generators"_s, &PackagePreset::Generators,
+ cmCMakePresetsGraphInternal::PresetVectorStringHelper, false)
+ .Bind("configurations"_s, &PackagePreset::Configurations,
+ cmCMakePresetsGraphInternal::PresetVectorStringHelper, false)
+ .Bind("variables"_s, &PackagePreset::Variables, VariablesHelper, false)
+ .Bind("configFile"_s, &PackagePreset::ConfigFile,
+ cmCMakePresetsGraphInternal::PresetStringHelper, false)
+ .Bind("output"_s, OutputHelper, false)
+ .Bind("packageName"_s, &PackagePreset::PackageName,
+ cmCMakePresetsGraphInternal::PresetStringHelper, false)
+ .Bind("packageVersion"_s, &PackagePreset::PackageVersion,
+ cmCMakePresetsGraphInternal::PresetStringHelper, false)
+ .Bind("packageDirectory"_s, &PackagePreset::PackageDirectory,
+ cmCMakePresetsGraphInternal::PresetStringHelper, false)
+ .Bind("vendorName"_s, &PackagePreset::VendorName,
+ cmCMakePresetsGraphInternal::PresetStringHelper, false)
+ .Bind("condition"_s, &PackagePreset::ConditionEvaluator,
+ cmCMakePresetsGraphInternal::PresetConditionHelper, false);
+}
+
+namespace cmCMakePresetsGraphInternal {
+cmCMakePresetsGraph::ReadFileResult PackagePresetsHelper(
+ std::vector<cmCMakePresetsGraph::PackagePreset>& out,
+ const Json::Value* value)
+{
+ static auto const helper =
+ cmJSONHelperBuilder<ReadFileResult>::Vector<PackagePreset>(
+ ReadFileResult::READ_OK, ReadFileResult::INVALID_PRESETS,
+ PackagePresetHelper);
+
+ return helper(out, value);
+}
+}
diff --git a/Source/cmCommands.cxx b/Source/cmCommands.cxx
index c6296f9..3bc4f0e 100644
--- a/Source/cmCommands.cxx
+++ b/Source/cmCommands.cxx
@@ -14,13 +14,13 @@
#include "cmAddLibraryCommand.h"
#include "cmAddSubDirectoryCommand.h"
#include "cmAddTestCommand.h"
+#include "cmBlockCommand.h"
#include "cmBreakCommand.h"
#include "cmBuildCommand.h"
#include "cmCMakeLanguageCommand.h"
#include "cmCMakeMinimumRequired.h"
#include "cmCMakePathCommand.h"
#include "cmCMakePolicyCommand.h"
-#include "cmCommand.h"
#include "cmConfigureFileCommand.h"
#include "cmContinueCommand.h"
#include "cmCreateTestSourceList.h"
@@ -127,6 +127,7 @@ void GetScriptingCommands(cmState* state)
state->AddFlowControlCommand("macro", cmMacroCommand);
state->AddFlowControlCommand("return", cmReturnCommand);
state->AddFlowControlCommand("while", cmWhileCommand);
+ state->AddFlowControlCommand("block", cmBlockCommand);
state->AddBuiltinCommand("cmake_language", cmCMakeLanguageCommand);
state->AddBuiltinCommand("cmake_minimum_required", cmCMakeMinimumRequired);
@@ -199,6 +200,10 @@ void GetScriptingCommands(cmState* state)
"An ENDWHILE command was found outside of a proper "
"WHILE ENDWHILE structure. Or its arguments did not "
"match the opening WHILE command.");
+ state->AddUnexpectedFlowControlCommand(
+ "endblock",
+ "An ENDBLOCK command was found outside of a proper "
+ "BLOCK ENDBLOCK structure.");
#if !defined(CMAKE_BOOTSTRAP)
state->AddBuiltinCommand("cmake_host_system_information",
@@ -264,9 +269,8 @@ void GetProjectCommands(cmState* state)
cmTargetLinkLibrariesCommand);
state->AddBuiltinCommand("target_link_options", cmTargetLinkOptionsCommand);
state->AddBuiltinCommand("target_sources", cmTargetSourcesCommand);
- state->AddBuiltinCommand("try_compile",
- cm::make_unique<cmTryCompileCommand>());
- state->AddBuiltinCommand("try_run", cm::make_unique<cmTryRunCommand>());
+ state->AddBuiltinCommand("try_compile", cmTryCompileCommand);
+ state->AddBuiltinCommand("try_run", cmTryRunCommand);
state->AddBuiltinCommand("target_precompile_headers",
cmTargetPrecompileHeadersCommand);
diff --git a/Source/cmCommonTargetGenerator.cxx b/Source/cmCommonTargetGenerator.cxx
index ba95168..5fe6756 100644
--- a/Source/cmCommonTargetGenerator.cxx
+++ b/Source/cmCommonTargetGenerator.cxx
@@ -9,6 +9,7 @@
#include "cmComputeLinkInformation.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalCommonGenerator.h"
+#include "cmGlobalGenerator.h"
#include "cmLocalCommonGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
@@ -175,6 +176,9 @@ std::vector<std::string> cmCommonTargetGenerator::GetLinkedTargetDirectories(
cmLocalGenerator* lg = linkee->GetLocalGenerator();
std::string di = cmStrCat(lg->GetCurrentBinaryDirectory(), '/',
lg->GetTargetDirectory(linkee));
+ if (lg->GetGlobalGenerator()->IsMultiConfig()) {
+ di = cmStrCat(di, '/', config);
+ }
dirs.push_back(std::move(di));
}
}
diff --git a/Source/cmConfigure.cmake.h.in b/Source/cmConfigure.cmake.h.in
index 6a419f6..31d03da 100644
--- a/Source/cmConfigure.cmake.h.in
+++ b/Source/cmConfigure.cmake.h.in
@@ -14,6 +14,10 @@
#pragma warning(disable : 1572) /* floating-point equality test */
#endif
+#if defined(__LCC__) && defined(__EDG__) && (__LCC__ == 123)
+#pragma diag_suppress 2910 /* excess -Wunused-function in 1.23.x */
+#endif
+
#cmakedefine HAVE_ENVIRON_NOT_REQUIRE_PROTOTYPE
#cmakedefine HAVE_UNSETENV
#cmakedefine CMake_USE_MACH_PARSER
diff --git a/Source/cmCoreTryCompile.cxx b/Source/cmCoreTryCompile.cxx
index 5418e7c..0a6c359 100644
--- a/Source/cmCoreTryCompile.cxx
+++ b/Source/cmCoreTryCompile.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmCoreTryCompile.h"
+#include <array>
#include <cstdio>
#include <cstring>
#include <set>
@@ -13,12 +14,14 @@
#include "cmsys/Directory.hxx"
+#include "cmArgumentParser.h"
#include "cmExportTryCompileFileGenerator.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
+#include "cmRange.h"
#include "cmState.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
@@ -28,142 +31,7 @@
#include "cmake.h"
namespace {
-class LanguageStandardState
-{
-public:
- LanguageStandardState(std::string&& lang)
- : StandardFlag(lang + "_STANDARD")
- , RequiredFlag(lang + "_STANDARD_REQUIRED")
- , ExtensionFlag(lang + "_EXTENSIONS")
- {
- }
-
- void Enabled(bool isEnabled) { this->IsEnabled = isEnabled; }
-
- bool UpdateIfMatches(std::vector<std::string> const& argv, size_t& index)
- {
- bool updated = false;
- if (argv[index] == this->StandardFlag) {
- this->DidStandard = true;
- this->StandardValue = argv[++index];
- updated = true;
- } else if (argv[index] == this->RequiredFlag) {
- this->DidStandardRequired = true;
- this->RequiredValue = argv[++index];
- updated = true;
- } else if (argv[index] == this->ExtensionFlag) {
- this->DidExtensions = true;
- this->ExtensionValue = argv[++index];
- updated = true;
- }
- return updated;
- }
-
- bool Validate(cmMakefile* const makefile) const
- {
- if (this->DidStandard) {
- makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat(this->StandardFlag,
- " allowed only in source file signature."));
- return false;
- }
- if (this->DidStandardRequired) {
- makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat(this->RequiredFlag,
- " allowed only in source file signature."));
- return false;
- }
- if (this->DidExtensions) {
- makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- cmStrCat(this->ExtensionFlag,
- " allowed only in source file signature."));
- return false;
- }
-
- return true;
- }
-
- bool DidNone() const
- {
- return !this->DidStandard && !this->DidStandardRequired &&
- !this->DidExtensions;
- }
-
- void LoadUnsetPropertyValues(cmMakefile* const makefile, bool honorStandard,
- bool warnCMP0067,
- std::vector<std::string>& warnCMP0067Variables)
- {
- if (!this->IsEnabled) {
- return;
- }
-
- auto lookupStdVar = [&](std::string const& var) -> std::string {
- std::string value = makefile->GetSafeDefinition(var);
- if (warnCMP0067 && !value.empty()) {
- value.clear();
- warnCMP0067Variables.emplace_back(var);
- }
- return value;
- };
-
- if (honorStandard || warnCMP0067) {
- if (!this->DidStandard) {
- this->StandardValue =
- lookupStdVar(cmStrCat("CMAKE_", this->StandardFlag));
- }
- if (!this->DidStandardRequired) {
- this->RequiredValue =
- lookupStdVar(cmStrCat("CMAKE_", this->RequiredFlag));
- }
- if (!this->DidExtensions) {
- this->ExtensionValue =
- lookupStdVar(cmStrCat("CMAKE_", this->ExtensionFlag));
- }
- }
- }
-
- void WriteProperties(FILE* fout, std::string const& targetName) const
- {
- if (!this->IsEnabled) {
- return;
- }
-
- auto writeProp = [&](std::string const& prop, std::string const& value) {
- fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n",
- targetName.c_str(),
- cmOutputConverter::EscapeForCMake(prop).c_str(),
- cmOutputConverter::EscapeForCMake(value).c_str());
- };
-
- if (!this->StandardValue.empty()) {
- writeProp(this->StandardFlag, this->StandardValue);
- }
- if (!this->RequiredValue.empty()) {
- writeProp(this->RequiredFlag, this->RequiredValue);
- }
- if (!this->ExtensionValue.empty()) {
- writeProp(this->ExtensionFlag, this->ExtensionValue);
- }
- }
-
-private:
- bool IsEnabled = false;
- bool DidStandard = false;
- bool DidStandardRequired = false;
- bool DidExtensions = false;
-
- std::string StandardFlag;
- std::string RequiredFlag;
- std::string ExtensionFlag;
-
- std::string StandardValue;
- std::string RequiredValue;
- std::string ExtensionValue;
-};
-
+constexpr const char* unique_binary_directory = "CMAKE_BINARY_DIR_USE_MKDTEMP";
constexpr size_t lang_property_start = 0;
constexpr size_t lang_property_size = 4;
constexpr size_t pie_property_start = 4;
@@ -233,114 +101,205 @@ std::set<std::string> const ghs_platform_vars{
"GHS_OS_ROOT", "GHS_OS_DIR", "GHS_BSP_NAME",
"GHS_OS_DIR_OPTION"
};
+using Arguments = cmCoreTryCompile::Arguments;
+
+ArgumentParser::Continue TryCompileLangProp(Arguments& args,
+ cm::string_view key,
+ cm::string_view val)
+{
+ args.LangProps[std::string(key)] = std::string(val);
+ return ArgumentParser::Continue::No;
}
-int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
- bool isTryRun)
+ArgumentParser::Continue TryCompileCompileDefs(Arguments& args,
+ cm::string_view val)
+{
+ cmExpandList(val, args.CompileDefs);
+ return ArgumentParser::Continue::Yes;
+}
+
+#define BIND_LANG_PROPS(lang) \
+ Bind(#lang "_STANDARD"_s, TryCompileLangProp) \
+ .Bind(#lang "_STANDARD_REQUIRED"_s, TryCompileLangProp) \
+ .Bind(#lang "_EXTENSIONS"_s, TryCompileLangProp)
+
+auto const TryCompileBaseArgParser =
+ cmArgumentParser<Arguments>{}
+ .Bind(0, &Arguments::CompileResultVariable)
+ .Bind("SOURCES"_s, &Arguments::Sources)
+ .Bind("CMAKE_FLAGS"_s, &Arguments::CMakeFlags)
+ .Bind("COMPILE_DEFINITIONS"_s, TryCompileCompileDefs,
+ ArgumentParser::ExpectAtLeast{ 0 })
+ .Bind("LINK_LIBRARIES"_s, &Arguments::LinkLibraries)
+ .Bind("LINK_OPTIONS"_s, &Arguments::LinkOptions)
+ .Bind("__CMAKE_INTERNAL"_s, &Arguments::CMakeInternal)
+ .Bind("COPY_FILE"_s, &Arguments::CopyFileTo)
+ .Bind("COPY_FILE_ERROR"_s, &Arguments::CopyFileError)
+ .BIND_LANG_PROPS(C)
+ .BIND_LANG_PROPS(CUDA)
+ .BIND_LANG_PROPS(CXX)
+ .BIND_LANG_PROPS(HIP)
+ .BIND_LANG_PROPS(OBJC)
+ .BIND_LANG_PROPS(OBJCXX)
+ /* keep semicolon on own line */;
+
+auto const TryCompileArgParser =
+ cmArgumentParser<Arguments>{ TryCompileBaseArgParser }.Bind(
+ "OUTPUT_VARIABLE"_s, &Arguments::OutputVariable)
+ /* keep semicolon on own line */;
+
+auto const TryCompileOldArgParser =
+ cmArgumentParser<Arguments>{ TryCompileArgParser }
+ .Bind(1, &Arguments::BinaryDirectory)
+ .Bind(2, &Arguments::SourceDirectoryOrFile)
+ .Bind(3, &Arguments::ProjectName)
+ .Bind(4, &Arguments::TargetName)
+ /* keep semicolon on own line */;
+
+auto const TryRunArgParser =
+ cmArgumentParser<Arguments>{ TryCompileBaseArgParser }
+ .Bind("COMPILE_OUTPUT_VARIABLE"_s, &Arguments::CompileOutputVariable)
+ .Bind("RUN_OUTPUT_VARIABLE"_s, &Arguments::RunOutputVariable)
+ .Bind("RUN_OUTPUT_STDOUT_VARIABLE"_s, &Arguments::RunOutputStdOutVariable)
+ .Bind("RUN_OUTPUT_STDERR_VARIABLE"_s, &Arguments::RunOutputStdErrVariable)
+ .Bind("WORKING_DIRECTORY"_s, &Arguments::RunWorkingDirectory)
+ .Bind("ARGS"_s, &Arguments::RunArgs)
+ /* keep semicolon on own line */;
+
+auto const TryRunOldArgParser =
+ cmArgumentParser<Arguments>{ TryCompileOldArgParser }
+ .Bind("COMPILE_OUTPUT_VARIABLE"_s, &Arguments::CompileOutputVariable)
+ .Bind("RUN_OUTPUT_VARIABLE"_s, &Arguments::RunOutputVariable)
+ .Bind("RUN_OUTPUT_STDOUT_VARIABLE"_s, &Arguments::RunOutputStdOutVariable)
+ .Bind("RUN_OUTPUT_STDERR_VARIABLE"_s, &Arguments::RunOutputStdErrVariable)
+ .Bind("WORKING_DIRECTORY"_s, &Arguments::RunWorkingDirectory)
+ .Bind("ARGS"_s, &Arguments::RunArgs)
+ /* keep semicolon on own line */;
+
+#undef BIND_LANG_PROPS
+}
+
+Arguments cmCoreTryCompile::ParseArgs(
+ const cmRange<std::vector<std::string>::const_iterator>& args,
+ const cmArgumentParser<Arguments>& parser,
+ std::vector<std::string>& unparsedArguments)
+{
+ auto arguments = parser.Parse(args, &unparsedArguments, 0);
+ if (!arguments.MaybeReportError(*(this->Makefile)) &&
+ !unparsedArguments.empty()) {
+ std::string m = "Unknown arguments:";
+ for (const auto& i : unparsedArguments) {
+ m = cmStrCat(m, "\n \"", i, "\"");
+ }
+ this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m);
+ }
+ return arguments;
+}
+
+Arguments cmCoreTryCompile::ParseArgs(
+ cmRange<std::vector<std::string>::const_iterator> args, bool isTryRun)
+{
+ std::vector<std::string> unparsedArguments;
+ if (cmHasLiteralPrefix(*(++args.begin()), "SOURCE")) {
+ // New signature.
+ auto arguments =
+ this->ParseArgs(args, isTryRun ? TryRunArgParser : TryCompileArgParser,
+ unparsedArguments);
+ arguments.BinaryDirectory = unique_binary_directory;
+ return arguments;
+ }
+
+ // Old signature.
+ auto arguments = this->ParseArgs(
+ args, isTryRun ? TryRunOldArgParser : TryCompileOldArgParser,
+ unparsedArguments);
+ // For historical reasons, treat some empty-valued keyword
+ // arguments as if they were not specified at all.
+ if (arguments.OutputVariable && arguments.OutputVariable->empty()) {
+ arguments.OutputVariable = cm::nullopt;
+ }
+ if (isTryRun) {
+ if (arguments.CompileOutputVariable &&
+ arguments.CompileOutputVariable->empty()) {
+ arguments.CompileOutputVariable = cm::nullopt;
+ }
+ if (arguments.RunOutputVariable && arguments.RunOutputVariable->empty()) {
+ arguments.RunOutputVariable = cm::nullopt;
+ }
+ if (arguments.RunOutputStdOutVariable &&
+ arguments.RunOutputStdOutVariable->empty()) {
+ arguments.RunOutputStdOutVariable = cm::nullopt;
+ }
+ if (arguments.RunOutputStdErrVariable &&
+ arguments.RunOutputStdErrVariable->empty()) {
+ arguments.RunOutputStdErrVariable = cm::nullopt;
+ }
+ if (arguments.RunWorkingDirectory &&
+ arguments.RunWorkingDirectory->empty()) {
+ arguments.RunWorkingDirectory = cm::nullopt;
+ }
+ }
+ return arguments;
+}
+
+bool cmCoreTryCompile::TryCompileCode(Arguments& arguments,
+ cmStateEnums::TargetType targetType)
{
- this->BinaryDirectory = argv[1];
this->OutputFile.clear();
// which signature were we called with ?
this->SrcFileSignature = true;
- cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE;
- cmValue tt = this->Makefile->GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE");
- if (!isTryRun && cmNonempty(tt)) {
- if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) {
- targetType = cmStateEnums::EXECUTABLE;
- } else if (*tt ==
- cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY)) {
- targetType = cmStateEnums::STATIC_LIBRARY;
- } else {
+ bool useUniqueBinaryDirectory = false;
+ std::string sourceDirectory;
+ std::string projectName;
+ std::string targetName;
+ if (arguments.SourceDirectoryOrFile && arguments.ProjectName) {
+ this->SrcFileSignature = false;
+ sourceDirectory = *arguments.SourceDirectoryOrFile;
+ projectName = *arguments.ProjectName;
+ if (arguments.TargetName) {
+ targetName = *arguments.TargetName;
+ }
+ } else {
+ projectName = "CMAKE_TRY_COMPILE";
+ /* Use a random file name to avoid rapid creation and deletion
+ of the same executable name (some filesystems fail on that). */
+ char targetNameBuf[64];
+ snprintf(targetNameBuf, sizeof(targetNameBuf), "cmTC_%05x",
+ cmSystemTools::RandomSeed() & 0xFFFFF);
+ targetName = targetNameBuf;
+ }
+
+ if (!arguments.BinaryDirectory || arguments.BinaryDirectory->empty()) {
+ this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
+ "No <bindir> specified.");
+ return false;
+ }
+ if (*arguments.BinaryDirectory == unique_binary_directory) {
+ // leave empty until we're ready to create it, so we don't try to remove
+ // a non-existing directory if we abort due to e.g. bad arguments
+ this->BinaryDirectory.clear();
+ useUniqueBinaryDirectory = true;
+ } else {
+ if (!cmSystemTools::FileIsFullPath(*arguments.BinaryDirectory)) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
- cmStrCat("Invalid value '", *tt,
- "' for CMAKE_TRY_COMPILE_TARGET_TYPE. Only '",
- cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE),
- "' and '",
- cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY),
- "' are allowed."));
- return -1;
+ cmStrCat("<bindir> is not an absolute path:\n '",
+ *arguments.BinaryDirectory, "'"));
+ return false;
+ }
+ this->BinaryDirectory = *arguments.BinaryDirectory;
+ // compute the binary dir when TRY_COMPILE is called with a src file
+ // signature
+ if (this->SrcFileSignature) {
+ this->BinaryDirectory += "/CMakeFiles/CMakeTmp";
}
}
- std::string sourceDirectory = argv[2];
- std::string projectName;
- std::string targetName;
- std::vector<std::string> cmakeFlags(1, "CMAKE_FLAGS"); // fake argv[0]
- std::vector<std::string> compileDefs;
- std::string cmakeInternal;
- std::string outputVariable;
- std::string copyFile;
- std::string copyFileError;
- LanguageStandardState cState("C");
- LanguageStandardState cudaState("CUDA");
- LanguageStandardState cxxState("CXX");
- LanguageStandardState hipState("HIP");
- LanguageStandardState objcState("OBJC");
- LanguageStandardState objcxxState("OBJCXX");
std::vector<std::string> targets;
- std::vector<std::string> linkOptions;
- std::string libsToLink = " ";
- bool useOldLinkLibs = true;
- char targetNameBuf[64];
- bool didOutputVariable = false;
- bool didCopyFile = false;
- bool didCopyFileError = false;
- bool useSources = argv[2] == "SOURCES";
- std::vector<std::string> sources;
-
- enum Doing
- {
- DoingNone,
- DoingCMakeFlags,
- DoingCompileDefinitions,
- DoingLinkOptions,
- DoingLinkLibraries,
- DoingOutputVariable,
- DoingCopyFile,
- DoingCopyFileError,
- DoingSources,
- DoingCMakeInternal
- };
- Doing doing = useSources ? DoingSources : DoingNone;
- for (size_t i = 3; i < argv.size(); ++i) {
- if (argv[i] == "CMAKE_FLAGS") {
- doing = DoingCMakeFlags;
- } else if (argv[i] == "COMPILE_DEFINITIONS") {
- doing = DoingCompileDefinitions;
- } else if (argv[i] == "LINK_OPTIONS") {
- doing = DoingLinkOptions;
- } else if (argv[i] == "LINK_LIBRARIES") {
- doing = DoingLinkLibraries;
- useOldLinkLibs = false;
- } else if (argv[i] == "OUTPUT_VARIABLE") {
- doing = DoingOutputVariable;
- didOutputVariable = true;
- } else if (argv[i] == "COPY_FILE") {
- doing = DoingCopyFile;
- didCopyFile = true;
- } else if (argv[i] == "COPY_FILE_ERROR") {
- doing = DoingCopyFileError;
- didCopyFileError = true;
- } else if (cState.UpdateIfMatches(argv, i) ||
- cxxState.UpdateIfMatches(argv, i) ||
- cudaState.UpdateIfMatches(argv, i) ||
- hipState.UpdateIfMatches(argv, i) ||
- objcState.UpdateIfMatches(argv, i) ||
- objcxxState.UpdateIfMatches(argv, i)) {
- continue;
- } else if (argv[i] == "__CMAKE_INTERNAL") {
- doing = DoingCMakeInternal;
- } else if (doing == DoingCMakeFlags) {
- cmakeFlags.emplace_back(argv[i]);
- } else if (doing == DoingCompileDefinitions) {
- cmExpandList(argv[i], compileDefs);
- } else if (doing == DoingLinkOptions) {
- linkOptions.emplace_back(argv[i]);
- } else if (doing == DoingLinkLibraries) {
- libsToLink += "\"" + cmTrimWhitespace(argv[i]) + "\" ";
- if (cmTarget* tgt = this->Makefile->FindTargetToUse(argv[i])) {
+ if (arguments.LinkLibraries) {
+ for (std::string const& i : *arguments.LinkLibraries) {
+ if (cmTarget* tgt = this->Makefile->FindTargetToUse(i)) {
switch (tgt->GetType()) {
case cmStateEnums::SHARED_LIBRARY:
case cmStateEnums::STATIC_LIBRARY:
@@ -359,114 +318,73 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
"IMPORTED LINK_LIBRARIES. Got ",
tgt->GetName(), " of type ",
cmState::GetTargetTypeName(tgt->GetType()), "."));
- return -1;
+ return false;
}
if (tgt->IsImported()) {
- targets.emplace_back(argv[i]);
+ targets.emplace_back(i);
}
}
- } else if (doing == DoingOutputVariable) {
- outputVariable = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCopyFile) {
- copyFile = argv[i];
- doing = DoingNone;
- } else if (doing == DoingCopyFileError) {
- copyFileError = argv[i];
- doing = DoingNone;
- } else if (doing == DoingSources) {
- sources.emplace_back(argv[i]);
- } else if (doing == DoingCMakeInternal) {
- cmakeInternal = argv[i];
- doing = DoingNone;
- } else if (i == 3) {
- this->SrcFileSignature = false;
- projectName = argv[i];
- } else if (i == 4 && !this->SrcFileSignature) {
- targetName = argv[i];
- } else {
- std::ostringstream m;
- m << "try_compile given unknown argument \"" << argv[i] << "\".";
- this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, m.str());
}
}
- if (didCopyFile && copyFile.empty()) {
+ if (arguments.CopyFileTo && arguments.CopyFileTo->empty()) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"COPY_FILE must be followed by a file path");
- return -1;
+ return false;
}
- if (didCopyFileError && copyFileError.empty()) {
+ if (arguments.CopyFileError && arguments.CopyFileError->empty()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"COPY_FILE_ERROR must be followed by a variable name");
- return -1;
+ return false;
}
- if (didCopyFileError && !didCopyFile) {
+ if (arguments.CopyFileError && !arguments.CopyFileTo) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"COPY_FILE_ERROR may be used only with COPY_FILE");
- return -1;
- }
-
- if (didOutputVariable && outputVariable.empty()) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "OUTPUT_VARIABLE must be followed by a variable name");
- return -1;
+ return false;
}
- if (useSources && sources.empty()) {
+ if (arguments.Sources && arguments.Sources->empty()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"SOURCES must be followed by at least one source file");
- return -1;
+ return false;
}
+ // only valid for srcfile signatures
if (!this->SrcFileSignature) {
- if (!cState.Validate(this->Makefile)) {
- return -1;
- }
- if (!cudaState.Validate(this->Makefile)) {
- return -1;
- }
- if (!hipState.Validate(this->Makefile)) {
- return -1;
- }
- if (!cxxState.Validate(this->Makefile)) {
- return -1;
- }
- if (!objcState.Validate(this->Makefile)) {
- return -1;
- }
- if (!objcxxState.Validate(this->Makefile)) {
- return -1;
+ if (!arguments.LangProps.empty()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(arguments.LangProps.begin()->first,
+ " allowed only in source file signature."));
+ return false;
}
- }
-
- // compute the binary dir when TRY_COMPILE is called with a src file
- // signature
- if (this->SrcFileSignature) {
- this->BinaryDirectory += "/CMakeFiles/CMakeTmp";
- } else {
- // only valid for srcfile signatures
- if (!compileDefs.empty()) {
+ if (!arguments.CompileDefs.empty()) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"COMPILE_DEFINITIONS specified on a srcdir type TRY_COMPILE");
- return -1;
+ return false;
}
- if (!copyFile.empty()) {
+ if (arguments.CopyFileTo) {
this->Makefile->IssueMessage(
MessageType::FATAL_ERROR,
"COPY_FILE specified on a srcdir type TRY_COMPILE");
- return -1;
+ return false;
}
}
// make sure the binary directory exists
- cmSystemTools::MakeDirectory(this->BinaryDirectory);
+ if (useUniqueBinaryDirectory) {
+ this->BinaryDirectory =
+ cmStrCat(this->Makefile->GetHomeOutputDirectory(),
+ "/CMakeFiles/CMakeScratch/TryCompile-XXXXXX");
+ cmSystemTools::MakeTempDirectory(this->BinaryDirectory);
+ } else {
+ cmSystemTools::MakeDirectory(this->BinaryDirectory);
+ }
// do not allow recursive try Compiles
if (this->BinaryDirectory == this->Makefile->GetHomeOutputDirectory()) {
@@ -474,7 +392,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
e << "Attempt at a recursive or nested TRY_COMPILE in directory\n"
<< " " << this->BinaryDirectory << "\n";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return -1;
+ return false;
}
std::string outFileName = this->BinaryDirectory + "/CMakeLists.txt";
@@ -485,8 +403,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
cmSystemTools::RemoveFile(ccFile);
// Choose sources.
- if (!useSources) {
- sources.emplace_back(argv[2]);
+ std::vector<std::string> sources;
+ if (arguments.Sources) {
+ sources = std::move(*arguments.Sources);
+ } else {
+ // TODO: ensure SourceDirectoryOrFile has a value
+ sources.emplace_back(*arguments.SourceDirectoryOrFile);
}
// Detect languages to enable.
@@ -508,7 +430,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
err << cmJoin(langs, " ");
err << "\nSee project() command to enable other languages.";
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, err.str());
- return -1;
+ return false;
}
}
@@ -535,7 +457,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
<< cmSystemTools::GetLastSystemError();
/* clang-format on */
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, e.str());
- return -1;
+ return false;
}
cmValue def = this->Makefile->GetDefinition("CMAKE_MODULE_PATH");
@@ -598,13 +520,22 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
}
fprintf(fout, "project(CMAKE_TRY_COMPILE%s)\n", projectLangs.c_str());
- if (cmakeInternal == "ABI") {
+ if (arguments.CMakeInternal == "ABI") {
// This is the ABI detection step, also used for implicit includes.
// Erase any include_directories() calls from the toolchain file so
// that we do not see them as implicit. Our ABI detection source
// does not include any system headers anyway.
fprintf(fout,
"set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES \"\")\n");
+
+ // The link and compile lines for ABI detection step need to not use
+ // response files so we can extract implicit includes given to
+ // the underlying host compiler
+ if (testLangs.find("CUDA") != testLangs.end()) {
+ fprintf(fout, "set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES OFF)\n");
+ fprintf(fout, "set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES OFF)\n");
+ fprintf(fout, "set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS OFF)\n");
+ }
}
fprintf(fout, "set(CMAKE_VERBOSE_MAKEFILE 1)\n");
for (std::string const& li : testLangs) {
@@ -696,18 +627,12 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
fprintf(fout, "set(CMAKE_SUPPRESS_REGENERATION 1)\n");
fprintf(fout, "link_directories(${LINK_DIRECTORIES})\n");
// handle any compile flags we need to pass on
- if (!compileDefs.empty()) {
+ if (!arguments.CompileDefs.empty()) {
// Pass using bracket arguments to preserve content.
fprintf(fout, "add_definitions([==[%s]==])\n",
- cmJoin(compileDefs, "]==] [==[").c_str());
+ cmJoin(arguments.CompileDefs, "]==] [==[").c_str());
}
- /* Use a random file name to avoid rapid creation and deletion
- of the same executable name (some filesystems fail on that). */
- snprintf(targetNameBuf, sizeof(targetNameBuf), "cmTC_%05x",
- cmSystemTools::RandomSeed() & 0xFFFFF);
- targetName = targetNameBuf;
-
if (!targets.empty()) {
std::string fname = "/" + std::string(targetName) + "Targets.cmake";
cmExportTryCompileFileGenerator tcfg(gg, targets, this->Makefile,
@@ -719,7 +644,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
this->Makefile->IssueMessage(MessageType::FATAL_ERROR,
"could not write export file.");
fclose(fout);
- return -1;
+ return false;
}
fprintf(fout, "\ninclude(\"${CMAKE_CURRENT_LIST_DIR}/%s\")\n\n",
fname.c_str());
@@ -763,24 +688,16 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
fprintf(fout, " \"%s\"", si.c_str());
// Add dependencies on any non-temporary sources.
- if (si.find("CMakeTmp") == std::string::npos) {
+ if (!IsTemporary(si)) {
this->Makefile->AddCMakeDependFile(si);
}
}
fprintf(fout, ")\n");
- cState.Enabled(testLangs.find("C") != testLangs.end());
- cxxState.Enabled(testLangs.find("CXX") != testLangs.end());
- cudaState.Enabled(testLangs.find("CUDA") != testLangs.end());
- hipState.Enabled(testLangs.find("HIP") != testLangs.end());
- objcState.Enabled(testLangs.find("OBJC") != testLangs.end());
- objcxxState.Enabled(testLangs.find("OBJCXX") != testLangs.end());
-
bool warnCMP0067 = false;
bool honorStandard = true;
- if (cState.DidNone() && cxxState.DidNone() && objcState.DidNone() &&
- objcxxState.DidNone() && cudaState.DidNone() && hipState.DidNone()) {
+ if (arguments.LangProps.empty()) {
switch (this->Makefile->GetPolicyStatus(cmPolicies::CMP0067)) {
case cmPolicies::WARN:
warnCMP0067 = this->Makefile->PolicyOptionalWarningEnabled(
@@ -805,18 +722,33 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
std::vector<std::string> warnCMP0067Variables;
- cState.LoadUnsetPropertyValues(this->Makefile, honorStandard, warnCMP0067,
- warnCMP0067Variables);
- cxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
- warnCMP0067, warnCMP0067Variables);
- cudaState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
- warnCMP0067, warnCMP0067Variables);
- hipState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
- warnCMP0067, warnCMP0067Variables);
- objcState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
- warnCMP0067, warnCMP0067Variables);
- objcxxState.LoadUnsetPropertyValues(this->Makefile, honorStandard,
- warnCMP0067, warnCMP0067Variables);
+ if (honorStandard || warnCMP0067) {
+ static std::array<std::string, 6> const possibleLangs{
+ { "C", "CXX", "CUDA", "HIP", "OBJC", "OBJCXX" }
+ };
+ static std::array<cm::string_view, 3> const langPropSuffixes{
+ { "_STANDARD"_s, "_STANDARD_REQUIRED"_s, "_EXTENSIONS"_s }
+ };
+ for (std::string const& lang : possibleLangs) {
+ if (testLangs.find(lang) == testLangs.end()) {
+ continue;
+ }
+ for (cm::string_view propSuffix : langPropSuffixes) {
+ std::string langProp = cmStrCat(lang, propSuffix);
+ if (!arguments.LangProps.count(langProp)) {
+ std::string langPropVar = cmStrCat("CMAKE_"_s, langProp);
+ std::string value = this->Makefile->GetSafeDefinition(langPropVar);
+ if (warnCMP0067 && !value.empty()) {
+ value.clear();
+ warnCMP0067Variables.emplace_back(langPropVar);
+ }
+ if (!value.empty()) {
+ arguments.LangProps[langProp] = value;
+ }
+ }
+ }
+ }
+ }
if (!warnCMP0067Variables.empty()) {
std::ostringstream w;
@@ -832,17 +764,20 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
this->Makefile->IssueMessage(MessageType::AUTHOR_WARNING, w.str());
}
- cState.WriteProperties(fout, targetName);
- cxxState.WriteProperties(fout, targetName);
- cudaState.WriteProperties(fout, targetName);
- hipState.WriteProperties(fout, targetName);
- objcState.WriteProperties(fout, targetName);
- objcxxState.WriteProperties(fout, targetName);
+ for (auto const& p : arguments.LangProps) {
+ if (p.second.empty()) {
+ continue;
+ }
+ fprintf(fout, "set_property(TARGET %s PROPERTY %s %s)\n",
+ targetName.c_str(),
+ cmOutputConverter::EscapeForCMake(p.first).c_str(),
+ cmOutputConverter::EscapeForCMake(p.second).c_str());
+ }
- if (!linkOptions.empty()) {
+ if (!arguments.LinkOptions.empty()) {
std::vector<std::string> options;
- options.reserve(linkOptions.size());
- for (const auto& option : linkOptions) {
+ options.reserve(arguments.LinkOptions.size());
+ for (const auto& option : arguments.LinkOptions) {
options.emplace_back(cmOutputConverter::EscapeForCMake(option));
}
@@ -856,15 +791,18 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
}
}
- if (useOldLinkLibs) {
- fprintf(fout, "target_link_libraries(%s ${LINK_LIBRARIES})\n",
- targetName.c_str());
- } else {
+ if (arguments.LinkLibraries) {
+ std::string libsToLink = " ";
+ for (std::string const& i : *arguments.LinkLibraries) {
+ libsToLink += "\"" + cmTrimWhitespace(i) + "\" ";
+ }
fprintf(fout, "target_link_libraries(%s %s)\n", targetName.c_str(),
libsToLink.c_str());
+ } else {
+ fprintf(fout, "target_link_libraries(%s ${LINK_LIBRARIES})\n",
+ targetName.c_str());
}
fclose(fout);
- projectName = "CMAKE_TRY_COMPILE";
}
// Forward a set of variables to the inner project cache.
@@ -953,13 +891,13 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
kCMAKE_TRY_COMPILE_OSX_ARCHITECTURES)) {
vars.erase(kCMAKE_OSX_ARCHITECTURES);
std::string flag = "-DCMAKE_OSX_ARCHITECTURES=" + *tcArchs;
- cmakeFlags.emplace_back(std::move(flag));
+ arguments.CMakeFlags.emplace_back(std::move(flag));
}
for (std::string const& var : vars) {
if (cmValue val = this->Makefile->GetDefinition(var)) {
std::string flag = "-D" + var + "=" + *val;
- cmakeFlags.emplace_back(std::move(flag));
+ arguments.CMakeFlags.emplace_back(std::move(flag));
}
}
}
@@ -969,7 +907,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
for (std::string const& var : ghs_platform_vars) {
if (cmValue val = this->Makefile->GetDefinition(var)) {
std::string flag = "-D" + var + "=" + "'" + *val + "'";
- cmakeFlags.emplace_back(std::move(flag));
+ arguments.CMakeFlags.emplace_back(std::move(flag));
}
}
}
@@ -980,26 +918,27 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
// actually do the try compile now that everything is setup
int res = this->Makefile->TryCompile(
sourceDirectory, this->BinaryDirectory, projectName, targetName,
- this->SrcFileSignature, cmake::NO_BUILD_PARALLEL_LEVEL, &cmakeFlags,
- output);
+ this->SrcFileSignature, cmake::NO_BUILD_PARALLEL_LEVEL,
+ &arguments.CMakeFlags, output);
if (erroroc) {
cmSystemTools::SetErrorOccurred();
}
// set the result var to the return value to indicate success or failure
- this->Makefile->AddCacheDefinition(argv[0], (res == 0 ? "TRUE" : "FALSE"),
- "Result of TRY_COMPILE",
- cmStateEnums::INTERNAL);
+ this->Makefile->AddCacheDefinition(
+ *arguments.CompileResultVariable, (res == 0 ? "TRUE" : "FALSE"),
+ "Result of TRY_COMPILE", cmStateEnums::INTERNAL);
- if (!outputVariable.empty()) {
- this->Makefile->AddDefinition(outputVariable, output);
+ if (arguments.OutputVariable) {
+ this->Makefile->AddDefinition(*arguments.OutputVariable, output);
}
if (this->SrcFileSignature) {
std::string copyFileErrorMessage;
this->FindOutputFile(targetName, targetType);
- if ((res == 0) && !copyFile.empty()) {
+ if ((res == 0) && arguments.CopyFileTo) {
+ std::string const& copyFile = *arguments.CopyFileTo;
if (this->OutputFile.empty() ||
!cmSystemTools::CopyFileAlways(this->OutputFile, copyFile)) {
std::ostringstream emsg;
@@ -1012,19 +951,26 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv,
if (!this->FindErrorMessage.empty()) {
emsg << this->FindErrorMessage;
}
- if (copyFileError.empty()) {
+ if (!arguments.CopyFileError) {
this->Makefile->IssueMessage(MessageType::FATAL_ERROR, emsg.str());
- return -1;
+ return false;
}
copyFileErrorMessage = emsg.str();
}
}
- if (!copyFileError.empty()) {
+ if (arguments.CopyFileError) {
+ std::string const& copyFileError = *arguments.CopyFileError;
this->Makefile->AddDefinition(copyFileError, copyFileErrorMessage);
}
}
- return res;
+ return res == 0;
+}
+
+bool cmCoreTryCompile::IsTemporary(std::string const& path)
+{
+ return ((path.find("CMakeTmp") != std::string::npos) ||
+ (path.find("CMakeScratch") != std::string::npos));
}
void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
@@ -1033,11 +979,11 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
return;
}
- if (binDir.find("CMakeTmp") == std::string::npos) {
+ if (!IsTemporary(binDir)) {
cmSystemTools::Error(
"TRY_COMPILE attempt to remove -rf directory that does not contain "
- "CMakeTmp:" +
- binDir);
+ "CMakeTmp or CMakeScratch: \"" +
+ binDir + "\"");
return;
}
@@ -1083,6 +1029,10 @@ void cmCoreTryCompile::CleanupFiles(std::string const& binDir)
}
}
}
+
+ if (binDir.find("CMakeScratch") != std::string::npos) {
+ cmSystemTools::RemoveADirectory(binDir);
+ }
}
void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
@@ -1117,7 +1067,8 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
searchDirs.emplace_back(std::move(tmp));
}
searchDirs.emplace_back("/Debug");
-#if defined(__APPLE__)
+
+ // handle app-bundles (for targeting apple-platforms)
std::string app = "/" + targetName + ".app";
if (cmNonempty(config)) {
std::string tmp = cmStrCat('/', *config, app);
@@ -1126,7 +1077,7 @@ void cmCoreTryCompile::FindOutputFile(const std::string& targetName,
std::string tmp = "/Debug" + app;
searchDirs.emplace_back(std::move(tmp));
searchDirs.emplace_back(std::move(app));
-#endif
+
searchDirs.emplace_back("/Development");
for (std::string const& sdir : searchDirs) {
diff --git a/Source/cmCoreTryCompile.h b/Source/cmCoreTryCompile.h
index 594fd7f..b483f0f 100644
--- a/Source/cmCoreTryCompile.h
+++ b/Source/cmCoreTryCompile.h
@@ -4,28 +4,83 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#include <map>
#include <string>
#include <vector>
-#include "cmCommand.h"
+#include <cm/optional>
+
+#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
#include "cmStateTypes.h"
+class cmMakefile;
+template <typename Iter>
+class cmRange;
+
/** \class cmCoreTryCompile
* \brief Base class for cmTryCompileCommand and cmTryRunCommand
*
* cmCoreTryCompile implements the functionality to build a program.
* It is the base class for cmTryCompileCommand and cmTryRunCommand.
*/
-class cmCoreTryCompile : public cmCommand
+class cmCoreTryCompile
{
public:
-protected:
+ cmCoreTryCompile(cmMakefile* mf)
+ : Makefile(mf)
+ {
+ }
+
+ struct Arguments : public ArgumentParser::ParseResult
+ {
+ cm::optional<std::string> CompileResultVariable;
+ cm::optional<std::string> BinaryDirectory;
+ cm::optional<std::string> SourceDirectoryOrFile;
+ cm::optional<std::string> ProjectName;
+ cm::optional<std::string> TargetName;
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> Sources;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> CMakeFlags{
+ 1, "CMAKE_FLAGS"
+ }; // fake argv[0]
+ std::vector<std::string> CompileDefs;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>>
+ LinkLibraries;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> LinkOptions;
+ std::map<std::string, std::string> LangProps;
+ std::string CMakeInternal;
+ cm::optional<std::string> OutputVariable;
+ cm::optional<std::string> CopyFileTo;
+ cm::optional<std::string> CopyFileError;
+
+ // Argument for try_run only.
+ // Keep in sync with warnings in cmCoreTryCompile::ParseArgs.
+ cm::optional<std::string> CompileOutputVariable;
+ cm::optional<std::string> RunOutputVariable;
+ cm::optional<std::string> RunOutputStdOutVariable;
+ cm::optional<std::string> RunOutputStdErrVariable;
+ cm::optional<std::string> RunWorkingDirectory;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> RunArgs;
+ };
+
+ Arguments ParseArgs(cmRange<std::vector<std::string>::const_iterator> args,
+ bool isTryRun);
+
/**
- * This is the core code for try compile. It is here so that other
- * commands, such as TryRun can access the same logic without
- * duplication.
+ * This is the core code for try compile. It is here so that other commands,
+ * such as TryRun can access the same logic without duplication.
+ *
+ * This function requires at least two \p arguments and will crash if given
+ * fewer.
*/
- int TryCompileCode(std::vector<std::string> const& argv, bool isTryRun);
+ bool TryCompileCode(Arguments& arguments,
+ cmStateEnums::TargetType targetType);
+
+ /**
+ * Returns \c true if \p path resides within a CMake temporary directory,
+ * otherwise returns \c false.
+ */
+ static bool IsTemporary(std::string const& path);
/**
* This deletes all the files created by TryCompileCode.
@@ -46,4 +101,11 @@ protected:
std::string OutputFile;
std::string FindErrorMessage;
bool SrcFileSignature = false;
+ cmMakefile* Makefile;
+
+private:
+ Arguments ParseArgs(
+ const cmRange<std::vector<std::string>::const_iterator>& args,
+ const cmArgumentParser<Arguments>& parser,
+ std::vector<std::string>& unparsedArguments);
};
diff --git a/Source/cmCreateTestSourceList.cxx b/Source/cmCreateTestSourceList.cxx
index 2a52d1a..75c25e3 100644
--- a/Source/cmCreateTestSourceList.cxx
+++ b/Source/cmCreateTestSourceList.cxx
@@ -87,9 +87,7 @@ bool cmCreateTestSourceList(std::vector<std::string> const& args,
func_name = cmSystemTools::GetFilenameWithoutLastExtension(*i);
}
cmSystemTools::ConvertToUnixSlashes(func_name);
- std::replace(func_name.begin(), func_name.end(), ' ', '_');
- std::replace(func_name.begin(), func_name.end(), '/', '_');
- std::replace(func_name.begin(), func_name.end(), ':', '_');
+ func_name = cmSystemTools::MakeCidentifier(func_name);
bool already_declared =
std::find(tests_func_name.begin(), tests_func_name.end(), func_name) !=
tests_func_name.end();
diff --git a/Source/cmCxxModuleMapper.cxx b/Source/cmCxxModuleMapper.cxx
new file mode 100644
index 0000000..84691c9
--- /dev/null
+++ b/Source/cmCxxModuleMapper.cxx
@@ -0,0 +1,308 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmCxxModuleMapper.h"
+
+#include <cassert>
+#include <cstddef>
+#include <set>
+#include <sstream>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include <cm/string_view>
+#include <cmext/string_view>
+
+#include "cmScanDepFormat.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
+
+cm::optional<std::string> CxxModuleLocations::BmiGeneratorPathForModule(
+ std::string const& logical_name) const
+{
+ if (auto l = this->BmiLocationForModule(logical_name)) {
+ return this->PathForGenerator(*l);
+ }
+ return {};
+}
+
+namespace {
+
+std::string CxxModuleMapContentGcc(CxxModuleLocations const& loc,
+ cmScanDepInfo const& obj)
+{
+ std::stringstream mm;
+
+ // Documented in GCC's documentation. The format is a series of
+ // lines with a module name and the associated filename separated
+ // by spaces. The first line may use `$root` as the module name
+ // to specify a "repository root". That is used to anchor any
+ // relative paths present in the file (CMake should never
+ // generate any).
+
+ // Write the root directory to use for module paths.
+ mm << "$root " << loc.RootDirectory << "\n";
+
+ for (auto const& p : obj.Provides) {
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
+ mm << p.LogicalName << ' ' << *bmi_loc << '\n';
+ }
+ }
+ for (auto const& r : obj.Requires) {
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
+ mm << r.LogicalName << ' ' << *bmi_loc << '\n';
+ }
+ }
+
+ return mm.str();
+}
+
+std::string CxxModuleMapContentMsvc(CxxModuleLocations const& loc,
+ cmScanDepInfo const& obj,
+ CxxModuleUsage const& usages)
+{
+ std::stringstream mm;
+
+ // A response file of `-reference NAME=PATH` arguments.
+
+ // MSVC's command line only supports a single output. If more than one is
+ // expected, we cannot make a useful module map file.
+ if (obj.Provides.size() > 1) {
+ return {};
+ }
+
+ auto flag_for_method = [](LookupMethod method) -> cm::static_string_view {
+ switch (method) {
+ case LookupMethod::ByName:
+ return "-reference"_s;
+ case LookupMethod::IncludeAngle:
+ return "-headerUnit:angle"_s;
+ case LookupMethod::IncludeQuote:
+ return "-headerUnit:quote"_s;
+ }
+ assert(false && "unsupported lookup method");
+ return ""_s;
+ };
+
+ for (auto const& p : obj.Provides) {
+ if (p.IsInterface) {
+ mm << "-interface\n";
+ } else {
+ mm << "-internalPartition\n";
+ }
+
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
+ mm << "-ifcOutput " << *bmi_loc << '\n';
+ }
+ }
+
+ std::set<std::string> transitive_usage_directs;
+ std::set<std::string> transitive_usage_names;
+
+ for (auto const& r : obj.Requires) {
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName)) {
+ auto flag = flag_for_method(r.Method);
+
+ mm << flag << ' ' << r.LogicalName << '=' << *bmi_loc << "\n";
+ transitive_usage_directs.insert(r.LogicalName);
+
+ // Insert transitive usages.
+ auto transitive_usages = usages.Usage.find(r.LogicalName);
+ if (transitive_usages != usages.Usage.end()) {
+ transitive_usage_names.insert(transitive_usages->second.begin(),
+ transitive_usages->second.end());
+ }
+ }
+ }
+
+ for (auto const& transitive_name : transitive_usage_names) {
+ if (transitive_usage_directs.count(transitive_name)) {
+ continue;
+ }
+
+ auto module_ref = usages.Reference.find(transitive_name);
+ if (module_ref != usages.Reference.end()) {
+ auto flag = flag_for_method(module_ref->second.Method);
+ mm << flag << ' ' << transitive_name << '=' << module_ref->second.Path
+ << "\n";
+ }
+ }
+
+ return mm.str();
+}
+}
+
+bool CxxModuleUsage::AddReference(std::string const& logical,
+ std::string const& loc, LookupMethod method)
+{
+ auto r = this->Reference.find(logical);
+ if (r != this->Reference.end()) {
+ auto& ref = r->second;
+
+ if (ref.Path == loc && ref.Method == method) {
+ return true;
+ }
+
+ auto method_name = [](LookupMethod m) -> cm::static_string_view {
+ switch (m) {
+ case LookupMethod::ByName:
+ return "by-name"_s;
+ case LookupMethod::IncludeAngle:
+ return "include-angle"_s;
+ case LookupMethod::IncludeQuote:
+ return "include-quote"_s;
+ }
+ assert(false && "unsupported lookup method");
+ return ""_s;
+ };
+
+ cmSystemTools::Error(cmStrCat("Disagreement of the location of the '",
+ logical,
+ "' module. "
+ "Location A: '",
+ ref.Path, "' via ", method_name(ref.Method),
+ "; "
+ "Location B: '",
+ loc, "' via ", method_name(method), "."));
+ return false;
+ }
+
+ auto& ref = this->Reference[logical];
+ ref.Path = loc;
+ ref.Method = method;
+
+ return true;
+}
+
+cm::static_string_view CxxModuleMapExtension(
+ cm::optional<CxxModuleMapFormat> format)
+{
+ if (format) {
+ switch (*format) {
+ case CxxModuleMapFormat::Gcc:
+ return ".gcm"_s;
+ case CxxModuleMapFormat::Msvc:
+ return ".ifc"_s;
+ }
+ }
+
+ return ".bmi"_s;
+}
+
+std::set<std::string> CxxModuleUsageSeed(
+ CxxModuleLocations const& loc, std::vector<cmScanDepInfo> const& objects,
+ CxxModuleUsage& usages)
+{
+ // Track inner usages to populate usages from internal bits.
+ //
+ // This is a map of modules that required some other module that was not
+ // found to those that were not found.
+ std::map<std::string, std::set<std::string>> internal_usages;
+ std::set<std::string> unresolved;
+
+ for (cmScanDepInfo const& object : objects) {
+ // Add references for each of the provided modules.
+ for (auto const& p : object.Provides) {
+ if (auto bmi_loc = loc.BmiGeneratorPathForModule(p.LogicalName)) {
+ // XXX(cxx-modules): How to support header units?
+ usages.AddReference(p.LogicalName, loc.PathForGenerator(*bmi_loc),
+ LookupMethod::ByName);
+ }
+ }
+
+ // For each requires, pull in what is required.
+ for (auto const& r : object.Requires) {
+ // Find transitive usages.
+ auto transitive_usages = usages.Usage.find(r.LogicalName);
+ // Find the required name in the current target.
+ auto bmi_loc = loc.BmiGeneratorPathForModule(r.LogicalName);
+
+ for (auto const& p : object.Provides) {
+ auto& this_usages = usages.Usage[p.LogicalName];
+
+ // Add the direct usage.
+ this_usages.insert(r.LogicalName);
+
+ // Add the transitive usage.
+ if (transitive_usages != usages.Usage.end()) {
+ this_usages.insert(transitive_usages->second.begin(),
+ transitive_usages->second.end());
+ } else if (bmi_loc) {
+ // Mark that we need to update transitive usages later.
+ internal_usages[p.LogicalName].insert(r.LogicalName);
+ }
+ }
+
+ if (bmi_loc) {
+ usages.AddReference(r.LogicalName, loc.PathForGenerator(*bmi_loc),
+ r.Method);
+ }
+ }
+ }
+
+ // While we have internal usages to manage.
+ while (!internal_usages.empty()) {
+ size_t starting_size = internal_usages.size();
+
+ // For each internal usage.
+ for (auto usage = internal_usages.begin(); usage != internal_usages.end();
+ /* see end of loop */) {
+ auto& this_usages = usages.Usage[usage->first];
+
+ for (auto use = usage->second.begin(); use != usage->second.end();
+ /* see end of loop */) {
+ // Check if this required module uses other internal modules; defer
+ // if so.
+ if (internal_usages.count(*use)) {
+ // Advance the iterator.
+ ++use;
+ continue;
+ }
+
+ auto transitive_usages = usages.Usage.find(*use);
+ if (transitive_usages != usages.Usage.end()) {
+ this_usages.insert(transitive_usages->second.begin(),
+ transitive_usages->second.end());
+ }
+
+ // Remove the entry and advance the iterator.
+ use = usage->second.erase(use);
+ }
+
+ // Erase the entry if it doesn't have any remaining usages.
+ if (usage->second.empty()) {
+ usage = internal_usages.erase(usage);
+ } else {
+ ++usage;
+ }
+ }
+
+ // Check that at least one usage was resolved.
+ if (starting_size == internal_usages.size()) {
+ // Nothing could be resolved this loop; we have a cycle, so record the
+ // cycle and exit.
+ for (auto const& usage : internal_usages) {
+ unresolved.insert(usage.first);
+ }
+ break;
+ }
+ }
+
+ return unresolved;
+}
+
+std::string CxxModuleMapContent(CxxModuleMapFormat format,
+ CxxModuleLocations const& loc,
+ cmScanDepInfo const& obj,
+ CxxModuleUsage const& usages)
+{
+ switch (format) {
+ case CxxModuleMapFormat::Gcc:
+ return CxxModuleMapContentGcc(loc, obj);
+ case CxxModuleMapFormat::Msvc:
+ return CxxModuleMapContentMsvc(loc, obj, usages);
+ }
+
+ assert(false);
+ return {};
+}
diff --git a/Source/cmCxxModuleMapper.h b/Source/cmCxxModuleMapper.h
new file mode 100644
index 0000000..8526a07
--- /dev/null
+++ b/Source/cmCxxModuleMapper.h
@@ -0,0 +1,85 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <functional>
+#include <map>
+#include <set>
+#include <string>
+#include <vector>
+
+#include <cm/optional>
+#include <cmext/string_view>
+
+#include "cmScanDepFormat.h"
+
+enum class CxxModuleMapFormat
+{
+ Gcc,
+ Msvc,
+};
+
+struct CxxModuleLocations
+{
+ // The path from which all relative paths should be computed. If
+ // this is relative, it is relative to the compiler's working
+ // directory.
+ std::string RootDirectory;
+
+ // A function to convert a full path to a path for the generator.
+ std::function<std::string(std::string const&)> PathForGenerator;
+
+ // Lookup the BMI location of a logical module name.
+ std::function<cm::optional<std::string>(std::string const&)>
+ BmiLocationForModule;
+
+ // Returns the generator path (if known) for the BMI given a
+ // logical module name.
+ cm::optional<std::string> BmiGeneratorPathForModule(
+ std::string const& logical_name) const;
+};
+
+struct CxxModuleReference
+{
+ // The path to the module file used.
+ std::string Path;
+ // How the module was looked up.
+ LookupMethod Method;
+};
+
+struct CxxModuleUsage
+{
+ // The usage requirements for this object.
+ std::map<std::string, std::set<std::string>> Usage;
+
+ // The references for this object.
+ std::map<std::string, CxxModuleReference> Reference;
+
+ // Add a reference to a module.
+ //
+ // Returns `true` if it matches how it was found previously, `false` if it
+ // conflicts.
+ bool AddReference(std::string const& logical, std::string const& loc,
+ LookupMethod method);
+};
+
+// Return the extension to use for a given modulemap format.
+cm::static_string_view CxxModuleMapExtension(
+ cm::optional<CxxModuleMapFormat> format);
+
+// Fill in module usage information for internal usages.
+//
+// Returns the set of unresolved module usage requirements (these form an
+// import cycle).
+std::set<std::string> CxxModuleUsageSeed(
+ CxxModuleLocations const& loc, std::vector<cmScanDepInfo> const& objects,
+ CxxModuleUsage& usages);
+
+// Return the contents of the module map in the given format for the
+// object file.
+std::string CxxModuleMapContent(CxxModuleMapFormat format,
+ CxxModuleLocations const& loc,
+ cmScanDepInfo const& obj,
+ CxxModuleUsage const& usages);
diff --git a/Source/cmDefinePropertyCommand.cxx b/Source/cmDefinePropertyCommand.cxx
index faefcb8..31ee665 100644
--- a/Source/cmDefinePropertyCommand.cxx
+++ b/Source/cmDefinePropertyCommand.cxx
@@ -8,6 +8,7 @@
#include <cmext/string_view>
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmProperty.h"
@@ -51,8 +52,8 @@ bool cmDefinePropertyCommand(std::vector<std::string> const& args,
// Parse remaining arguments.
bool inherited = false;
std::string PropertyName;
- std::vector<std::string> BriefDocs;
- std::vector<std::string> FullDocs;
+ ArgumentParser::NonEmpty<std::vector<std::string>> BriefDocs;
+ ArgumentParser::NonEmpty<std::vector<std::string>> FullDocs;
std::string initializeFromVariable;
cmArgumentParser<void> parser;
diff --git a/Source/cmDocumentation.cxx b/Source/cmDocumentation.cxx
index 3619ade..d466a12 100644
--- a/Source/cmDocumentation.cxx
+++ b/Source/cmDocumentation.cxx
@@ -17,30 +17,32 @@
#include "cmVersion.h"
static const char* cmDocumentationStandardOptions[][2] = {
- { "--help,-help,-usage,-h,-H,/?", "Print usage information and exit." },
- { "--version,-version,/V [<f>]", "Print version number and exit." },
- { "--help-full [<f>]", "Print all help manuals and exit." },
- { "--help-manual <man> [<f>]", "Print one help manual and exit." },
- { "--help-manual-list [<f>]", "List help manuals available and exit." },
- { "--help-command <cmd> [<f>]", "Print help for one command and exit." },
- { "--help-command-list [<f>]",
+ { "-h,-H,--help,-help,-usage,/?", "Print usage information and exit." },
+ { "--version,-version,/V [<file>]", "Print version number and exit." },
+ { "--help-full [<file>]", "Print all help manuals and exit." },
+ { "--help-manual <man> [<file>]", "Print one help manual and exit." },
+ { "--help-manual-list [<file>]", "List help manuals available and exit." },
+ { "--help-command <cmd> [<file>]", "Print help for one command and exit." },
+ { "--help-command-list [<file>]",
"List commands with help available and exit." },
- { "--help-commands [<f>]", "Print cmake-commands manual and exit." },
- { "--help-module <mod> [<f>]", "Print help for one module and exit." },
- { "--help-module-list [<f>]", "List modules with help available and exit." },
- { "--help-modules [<f>]", "Print cmake-modules manual and exit." },
- { "--help-policy <cmp> [<f>]", "Print help for one policy and exit." },
- { "--help-policy-list [<f>]",
+ { "--help-commands [<file>]", "Print cmake-commands manual and exit." },
+ { "--help-module <mod> [<file>]", "Print help for one module and exit." },
+ { "--help-module-list [<file>]",
+ "List modules with help available and exit." },
+ { "--help-modules [<file>]", "Print cmake-modules manual and exit." },
+ { "--help-policy <cmp> [<file>]", "Print help for one policy and exit." },
+ { "--help-policy-list [<file>]",
"List policies with help available and exit." },
- { "--help-policies [<f>]", "Print cmake-policies manual and exit." },
- { "--help-property <prop> [<f>]", "Print help for one property and exit." },
- { "--help-property-list [<f>]",
+ { "--help-policies [<file>]", "Print cmake-policies manual and exit." },
+ { "--help-property <prop> [<file>]",
+ "Print help for one property and exit." },
+ { "--help-property-list [<file>]",
"List properties with help available and exit." },
- { "--help-properties [<f>]", "Print cmake-properties manual and exit." },
- { "--help-variable var [<f>]", "Print help for one variable and exit." },
- { "--help-variable-list [<f>]",
+ { "--help-properties [<file>]", "Print cmake-properties manual and exit." },
+ { "--help-variable var [<file>]", "Print help for one variable and exit." },
+ { "--help-variable-list [<file>]",
"List variables with help available and exit." },
- { "--help-variables [<f>]", "Print cmake-variables manual and exit." },
+ { "--help-variables [<file>]", "Print cmake-variables manual and exit." },
{ nullptr, nullptr }
};
diff --git a/Source/cmExecuteProcessCommand.cxx b/Source/cmExecuteProcessCommand.cxx
index 222ea80..7fbd826 100644
--- a/Source/cmExecuteProcessCommand.cxx
+++ b/Source/cmExecuteProcessCommand.cxx
@@ -47,7 +47,7 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
return false;
}
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
std::vector<std::vector<std::string>> Commands;
std::string OutputVariable;
@@ -95,14 +95,10 @@ bool cmExecuteProcessCommand(std::vector<std::string> const& args,
.Bind("COMMAND_ERROR_IS_FATAL"_s, &Arguments::CommandErrorIsFatal);
std::vector<std::string> unparsedArguments;
- std::vector<std::string> keywordsMissingValue;
- Arguments const arguments =
- parser.Parse(args, &unparsedArguments, &keywordsMissingValue);
+ Arguments const arguments = parser.Parse(args, &unparsedArguments);
- if (!keywordsMissingValue.empty()) {
- status.SetError(" called with no value for " +
- keywordsMissingValue.front() + ".");
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (!unparsedArguments.empty()) {
status.SetError(" given unknown argument \"" + unparsedArguments.front() +
diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h
index 0feaedf..ced3548 100644
--- a/Source/cmExecutionStatus.h
+++ b/Source/cmExecutionStatus.h
@@ -5,6 +5,7 @@
#include <cmConfigure.h> // IWYU pragma: keep
#include <string>
+#include <vector>
class cmMakefile;
@@ -27,8 +28,21 @@ public:
void SetError(std::string const& e) { this->Error = e; }
std::string const& GetError() const { return this->Error; }
- void SetReturnInvoked() { this->ReturnInvoked = true; }
+ void SetReturnInvoked()
+ {
+ this->Variables.clear();
+ this->ReturnInvoked = true;
+ }
+ void SetReturnInvoked(std::vector<std::string> variables)
+ {
+ this->Variables = std::move(variables);
+ this->ReturnInvoked = true;
+ }
bool GetReturnInvoked() const { return this->ReturnInvoked; }
+ const std::vector<std::string>& GetReturnVariables() const
+ {
+ return this->Variables;
+ }
void SetBreakInvoked() { this->BreakInvoked = true; }
bool GetBreakInvoked() const { return this->BreakInvoked; }
@@ -46,4 +60,5 @@ private:
bool BreakInvoked = false;
bool ContinueInvoked = false;
bool NestedError = false;
+ std::vector<std::string> Variables;
};
diff --git a/Source/cmExperimental.cxx b/Source/cmExperimental.cxx
new file mode 100644
index 0000000..922b53f
--- /dev/null
+++ b/Source/cmExperimental.cxx
@@ -0,0 +1,63 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#include "cmExperimental.h"
+
+#include <cassert>
+#include <cstddef>
+#include <string>
+
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmValue.h"
+
+namespace {
+
+/*
+ * The `Uuid` fields of these objects should change periodically.
+ * Search for other instances to keep the documentation and test suite
+ * up-to-date.
+ */
+
+struct FeatureData
+{
+ std::string const Uuid;
+ std::string const Variable;
+ std::string const Description;
+ bool Warned;
+} LookupTable[] = {
+ // CxxModuleCMakeApi
+ { "3c375311-a3c9-4396-a187-3227ef642046",
+ "CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API",
+ "CMake's C++ module support is experimental. It is meant only for "
+ "experimentation and feedback to CMake developers.",
+ false },
+};
+static_assert(sizeof(LookupTable) / sizeof(LookupTable[0]) ==
+ static_cast<size_t>(cmExperimental::Feature::Sentinel),
+ "Experimental feature lookup table mismatch");
+
+FeatureData& DataForFeature(cmExperimental::Feature f)
+{
+ assert(f != cmExperimental::Feature::Sentinel);
+ return LookupTable[static_cast<size_t>(f)];
+}
+}
+
+bool cmExperimental::HasSupportEnabled(cmMakefile const& mf, Feature f)
+{
+ bool enabled = false;
+ auto& data = DataForFeature(f);
+
+ auto value = mf.GetDefinition(data.Variable);
+ if (value == data.Uuid) {
+ enabled = true;
+ }
+
+ if (enabled && !data.Warned) {
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, data.Description);
+ data.Warned = true;
+ }
+
+ return enabled;
+}
diff --git a/Source/cmExperimental.h b/Source/cmExperimental.h
new file mode 100644
index 0000000..26e0d17
--- /dev/null
+++ b/Source/cmExperimental.h
@@ -0,0 +1,21 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+class cmMakefile;
+
+class cmExperimental
+{
+public:
+ enum class Feature
+ {
+ CxxModuleCMakeApi,
+
+ Sentinel,
+ };
+
+ static bool HasSupportEnabled(cmMakefile const& mf, Feature f);
+};
diff --git a/Source/cmExportBuildFileGenerator.cxx b/Source/cmExportBuildFileGenerator.cxx
index 6ce0c98..ed199ea 100644
--- a/Source/cmExportBuildFileGenerator.cxx
+++ b/Source/cmExportBuildFileGenerator.cxx
@@ -9,10 +9,13 @@
#include <sstream>
#include <utility>
+#include <cm/string_view>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmExportSet.h"
#include "cmFileSet.h"
+#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
@@ -23,6 +26,7 @@
#include "cmPolicies.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.h"
#include "cmValue.h"
@@ -139,11 +143,18 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateTargetFileSets(gte, os);
}
+ this->GenerateCxxModuleInformation(os);
+
// Generate import file content for each configuration.
for (std::string const& c : this->Configurations) {
this->GenerateImportConfig(os, c);
}
+ // Generate import file content for each configuration.
+ for (std::string const& c : this->Configurations) {
+ this->GenerateImportCxxModuleConfigTargetInclusion(c);
+ }
+
this->GenerateMissingTargetsCheckCode(os);
return true;
@@ -382,6 +393,21 @@ std::string cmExportBuildFileGenerator::GetFileSetDirectories(
std::any_of(directoryEntries.begin(), directoryEntries.end(),
EntryIsContextSensitive);
+ auto const& type = fileSet->GetType();
+ // C++ modules do not support interface file sets which are dependent upon
+ // the configuration.
+ if (contextSensitive &&
+ (type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
+ auto* mf = this->LG->GetMakefile();
+ std::ostringstream e;
+ e << "The \"" << gte->GetName() << "\" target's interface file set \""
+ << fileSet->GetName() << "\" of type \"" << type
+ << "\" contains context-sensitive base directory entries which is not "
+ "supported.";
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return std::string{};
+ }
+
for (auto const& directory : directories) {
auto dest = cmOutputConverter::EscapeForCMake(
directory, cmOutputConverter::WrapQuotes::NoWrap);
@@ -427,6 +453,21 @@ std::string cmExportBuildFileGenerator::GetFileSetFiles(cmGeneratorTarget* gte,
std::any_of(fileEntries.begin(), fileEntries.end(),
EntryIsContextSensitive);
+ auto const& type = fileSet->GetType();
+ // C++ modules do not support interface file sets which are dependent upon
+ // the configuration.
+ if (contextSensitive &&
+ (type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
+ auto* mf = this->LG->GetMakefile();
+ std::ostringstream e;
+ e << "The \"" << gte->GetName() << "\" target's interface file set \""
+ << fileSet->GetName() << "\" of type \"" << type
+ << "\" contains context-sensitive file entries which is not "
+ "supported.";
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return std::string{};
+ }
+
for (auto const& it : files) {
for (auto const& filename : it.second) {
auto escapedFile = cmOutputConverter::EscapeForCMake(
@@ -447,3 +488,60 @@ std::string cmExportBuildFileGenerator::GetFileSetFiles(cmGeneratorTarget* gte,
return cmJoin(resultVector, " ");
}
+
+std::string cmExportBuildFileGenerator::GetCxxModulesDirectory() const
+{
+ return this->CxxModulesDirectory;
+}
+
+void cmExportBuildFileGenerator::GenerateCxxModuleConfigInformation(
+ std::ostream& os) const
+{
+ const char* opt = "";
+ if (this->Configurations.size() > 1) {
+ // With more than one configuration, each individual file is optional.
+ opt = " OPTIONAL";
+ }
+
+ // Generate import file content for each configuration.
+ for (std::string c : this->Configurations) {
+ if (c.empty()) {
+ c = "noconfig";
+ }
+ os << "include(\"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-" << c << ".cmake\""
+ << opt << ")\n";
+ }
+}
+
+bool cmExportBuildFileGenerator::GenerateImportCxxModuleConfigTargetInclusion(
+ std::string config) const
+{
+ auto cxx_modules_dirname = this->GetCxxModulesDirectory();
+ if (cxx_modules_dirname.empty()) {
+ return true;
+ }
+
+ if (config.empty()) {
+ config = "noconfig";
+ }
+
+ std::string fileName = cmStrCat(this->FileDir, '/', cxx_modules_dirname,
+ "/cxx-modules-", config, ".cmake");
+
+ cmGeneratedFileStream os(fileName, true);
+ if (!os) {
+ std::string se = cmSystemTools::GetLastSystemError();
+ std::ostringstream e;
+ e << "cannot write to file \"" << fileName << "\": " << se;
+ cmSystemTools::Error(e.str());
+ return false;
+ }
+ os.SetCopyIfDifferent(true);
+
+ for (auto const* tgt : this->ExportedTargets) {
+ os << "include(\"${CMAKE_CURRENT_LIST_DIR}/target-" << tgt->GetExportName()
+ << '-' << config << ".cmake\")\n";
+ }
+
+ return true;
+}
diff --git a/Source/cmExportBuildFileGenerator.h b/Source/cmExportBuildFileGenerator.h
index 5681e8f..4636196 100644
--- a/Source/cmExportBuildFileGenerator.h
+++ b/Source/cmExportBuildFileGenerator.h
@@ -47,6 +47,16 @@ public:
}
void SetExportSet(cmExportSet*);
+ /** Set the name of the C++ module directory. */
+ void SetCxxModuleDirectory(std::string cxx_module_dir)
+ {
+ this->CxxModulesDirectory = std::move(cxx_module_dir);
+ }
+ const std::string& GetCxxModuleDirectory() const
+ {
+ return this->CxxModulesDirectory;
+ }
+
/** Set whether to append generated code to the output file. */
void SetAppendMode(bool append) { this->AppendMode = append; }
@@ -81,6 +91,10 @@ protected:
std::string GetFileSetFiles(cmGeneratorTarget* gte, cmFileSet* fileSet,
cmTargetExport* te) override;
+ std::string GetCxxModulesDirectory() const override;
+ void GenerateCxxModuleConfigInformation(std::ostream&) const override;
+ bool GenerateImportCxxModuleConfigTargetInclusion(std::string) const;
+
std::pair<std::vector<std::string>, std::string> FindBuildExportInfo(
cmGlobalGenerator* gg, const std::string& name);
@@ -88,4 +102,6 @@ protected:
cmExportSet* ExportSet;
std::vector<cmGeneratorTarget*> Exports;
cmLocalGenerator* LG;
+ // The directory for C++ module information.
+ std::string CxxModulesDirectory;
};
diff --git a/Source/cmExportCommand.cxx b/Source/cmExportCommand.cxx
index 63440a3..a58f2b7 100644
--- a/Source/cmExportCommand.cxx
+++ b/Source/cmExportCommand.cxx
@@ -7,13 +7,15 @@
#include <utility>
#include <cm/memory>
-#include <cmext/algorithm>
+#include <cm/optional>
#include <cmext/string_view>
#include "cmsys/RegularExpression.hxx"
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
#include "cmExecutionStatus.h"
+#include "cmExperimental.h"
#include "cmExportBuildAndroidMKGenerator.h"
#include "cmExportBuildFileGenerator.h"
#include "cmExportSet.h"
@@ -57,10 +59,11 @@ bool cmExportCommand(std::vector<std::string> const& args,
struct Arguments
{
std::string ExportSetName;
- std::vector<std::string> Targets;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> Targets;
std::string Namespace;
std::string Filename;
std::string AndroidMKFile;
+ std::string CxxModulesDirectory;
bool Append = false;
bool ExportOld = false;
};
@@ -69,6 +72,12 @@ bool cmExportCommand(std::vector<std::string> const& args,
.Bind("NAMESPACE"_s, &Arguments::Namespace)
.Bind("FILE"_s, &Arguments::Filename);
+ bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
+ status.GetMakefile(), cmExperimental::Feature::CxxModuleCMakeApi);
+ if (supportCxx20FileSetTypes) {
+ parser.Bind("CXX_MODULES_DIRECTORY"_s, &Arguments::CxxModulesDirectory);
+ }
+
if (args[0] == "EXPORT") {
parser.Bind("EXPORT"_s, &Arguments::ExportSetName);
} else {
@@ -79,9 +88,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
}
std::vector<std::string> unknownArgs;
- std::vector<std::string> keywordsMissingValue;
- Arguments const arguments =
- parser.Parse(args, &unknownArgs, &keywordsMissingValue);
+ Arguments const arguments = parser.Parse(args, &unknownArgs);
if (!unknownArgs.empty()) {
status.SetError("Unknown argument: \"" + unknownArgs.front() + "\".");
@@ -145,9 +152,8 @@ bool cmExportCommand(std::vector<std::string> const& args,
return false;
}
exportSet = &it->second;
- } else if (!arguments.Targets.empty() ||
- cm::contains(keywordsMissingValue, "TARGETS")) {
- for (std::string const& currentTarget : arguments.Targets) {
+ } else if (arguments.Targets) {
+ for (std::string const& currentTarget : *arguments.Targets) {
if (mf.IsAlias(currentTarget)) {
std::ostringstream e;
e << "given ALIAS target \"" << currentTarget
@@ -214,6 +220,7 @@ bool cmExportCommand(std::vector<std::string> const& args,
}
ebfg->SetExportFile(fname.c_str());
ebfg->SetNamespace(arguments.Namespace);
+ ebfg->SetCxxModuleDirectory(arguments.CxxModulesDirectory);
ebfg->SetAppendMode(arguments.Append);
if (exportSet != nullptr) {
ebfg->SetExportSet(exportSet);
diff --git a/Source/cmExportFileGenerator.cxx b/Source/cmExportFileGenerator.cxx
index 5a33349..50bc78c 100644
--- a/Source/cmExportFileGenerator.cxx
+++ b/Source/cmExportFileGenerator.cxx
@@ -939,13 +939,13 @@ void cmExportFileGenerator::GeneratePolicyHeaderCode(std::ostream& os)
// Isolate the file policy level.
// Support CMake versions as far back as 2.6 but also support using NEW
- // policy settings for up to CMake 3.22 (this upper limit may be reviewed
+ // policy settings for up to CMake 3.23 (this upper limit may be reviewed
// and increased from time to time). This reduces the opportunity for CMake
// warnings when an older export file is later used with newer CMake
// versions.
/* clang-format off */
os << "cmake_policy(PUSH)\n"
- << "cmake_policy(VERSION 2.8.3...3.22)\n";
+ << "cmake_policy(VERSION 2.8.3...3.23)\n";
/* clang-format on */
}
@@ -1095,6 +1095,10 @@ void cmExportFileGenerator::GenerateImportTargetCode(
<< " PROPERTY IMPORTED_NO_SYSTEM 1)\n";
}
+ if (target->GetPropertyAsBool("EXPORT_NO_SYSTEM")) {
+ os << "set_property(TARGET " << targetName << " PROPERTY SYSTEM 0)\n";
+ }
+
os << "\n";
}
@@ -1308,3 +1312,28 @@ void cmExportFileGenerator::GenerateTargetFileSets(cmGeneratorTarget* gte,
os << " )\nendif()\n\n";
}
}
+
+void cmExportFileGenerator::GenerateCxxModuleInformation(std::ostream& os)
+{
+ auto const cxx_module_dirname = this->GetCxxModulesDirectory();
+ if (cxx_module_dirname.empty()) {
+ return;
+ }
+
+ // Write the include.
+ os << "# Include C++ module properties\n"
+ << "include(\"${CMAKE_CURRENT_LIST_DIR}/" << cxx_module_dirname
+ << "/cxx-modules.cmake\")\n\n";
+
+ // Get the path to the file we're going to write.
+ std::string path = this->MainImportFile;
+ path = cmSystemTools::GetFilenamePath(path);
+ auto trampoline_path =
+ cmStrCat(path, '/', cxx_module_dirname, "/cxx-modules.cmake");
+
+ // Include all configuration-specific include files.
+ cmGeneratedFileStream ap(trampoline_path, true);
+ ap.SetCopyIfDifferent(true);
+
+ this->GenerateCxxModuleConfigInformation(ap);
+}
diff --git a/Source/cmExportFileGenerator.h b/Source/cmExportFileGenerator.h
index d27a555..fdda878 100644
--- a/Source/cmExportFileGenerator.h
+++ b/Source/cmExportFileGenerator.h
@@ -182,6 +182,8 @@ protected:
void GenerateTargetFileSets(cmGeneratorTarget* gte, std::ostream& os,
cmTargetExport* te = nullptr);
+ void GenerateCxxModuleInformation(std::ostream& os);
+
virtual std::string GetFileSetDirectories(cmGeneratorTarget* gte,
cmFileSet* fileSet,
cmTargetExport* te) = 0;
@@ -226,4 +228,7 @@ private:
virtual std::string InstallNameDir(cmGeneratorTarget const* target,
const std::string& config) = 0;
+
+ virtual std::string GetCxxModulesDirectory() const = 0;
+ virtual void GenerateCxxModuleConfigInformation(std::ostream& os) const = 0;
};
diff --git a/Source/cmExportInstallAndroidMKGenerator.cxx b/Source/cmExportInstallAndroidMKGenerator.cxx
index 4e4f8a1..d53254d 100644
--- a/Source/cmExportInstallAndroidMKGenerator.cxx
+++ b/Source/cmExportInstallAndroidMKGenerator.cxx
@@ -35,8 +35,7 @@ void cmExportInstallAndroidMKGenerator::GenerateImportHeaderCode(
for (size_t n = 0; n < numDotDot; n++) {
path += "/..";
}
- os << "_IMPORT_PREFIX := "
- << "$(LOCAL_PATH)" << path << "\n\n";
+ os << "_IMPORT_PREFIX := $(LOCAL_PATH)" << path << "\n\n";
for (std::unique_ptr<cmTargetExport> const& te :
this->IEGen->GetExportSet()->GetTargetExports()) {
// Collect import properties for this target.
diff --git a/Source/cmExportInstallFileGenerator.cxx b/Source/cmExportInstallFileGenerator.cxx
index adccdfe..7d8572d 100644
--- a/Source/cmExportInstallFileGenerator.cxx
+++ b/Source/cmExportInstallFileGenerator.cxx
@@ -7,6 +7,9 @@
#include <sstream>
#include <utility>
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
@@ -18,6 +21,7 @@
#include "cmInstallTargetGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
+#include "cmMessageType.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
#include "cmStateTypes.h"
@@ -162,10 +166,20 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->LoadConfigFiles(os);
+ bool result = true;
+
+ this->GenerateCxxModuleInformation(os);
+ if (requiresConfigFiles) {
+ for (std::string const& c : this->Configurations) {
+ if (!this->GenerateImportCxxModuleConfigTargetInclusion(c)) {
+ result = false;
+ }
+ }
+ }
+
this->CleanupTemporaryVariables(os);
this->GenerateImportedFileCheckLoop(os);
- bool result = true;
// Generate an import file for each configuration.
// Don't do this if we only export INTERFACE_LIBRARY targets.
if (requiresConfigFiles) {
@@ -562,6 +576,21 @@ std::string cmExportInstallFileGenerator::GetFileSetDirectories(
cge->Evaluate(gte->LocalGenerator, config, gte),
cmOutputConverter::WrapQuotes::NoWrap));
+ auto const& type = fileSet->GetType();
+ // C++ modules do not support interface file sets which are dependent upon
+ // the configuration.
+ if (cge->GetHadContextSensitiveCondition() &&
+ (type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
+ auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
+ std::ostringstream e;
+ e << "The \"" << gte->GetName() << "\" target's interface file set \""
+ << fileSet->GetName() << "\" of type \"" << type
+ << "\" contains context-sensitive base file entries which is not "
+ "supported.";
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return std::string{};
+ }
+
if (cge->GetHadContextSensitiveCondition() && configs.size() != 1) {
resultVector.push_back(
cmStrCat("\"$<$<CONFIG:", config, ">:", dest, ">\""));
@@ -610,6 +639,21 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
std::any_of(fileEntries.begin(), fileEntries.end(),
EntryIsContextSensitive);
+ auto const& type = fileSet->GetType();
+ // C++ modules do not support interface file sets which are dependent upon
+ // the configuration.
+ if (contextSensitive &&
+ (type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s)) {
+ auto* mf = this->IEGen->GetLocalGenerator()->GetMakefile();
+ std::ostringstream e;
+ e << "The \"" << gte->GetName() << "\" target's interface file set \""
+ << fileSet->GetName() << "\" of type \"" << type
+ << "\" contains context-sensitive base file entries which is not "
+ "supported.";
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+ return std::string{};
+ }
+
for (auto const& it : files) {
auto prefix = it.first.empty() ? "" : cmStrCat(it.first, '/');
for (auto const& filename : it.second) {
@@ -635,3 +679,65 @@ std::string cmExportInstallFileGenerator::GetFileSetFiles(
return cmJoin(resultVector, " ");
}
+
+std::string cmExportInstallFileGenerator::GetCxxModulesDirectory() const
+{
+ return IEGen->GetCxxModuleDirectory();
+}
+
+void cmExportInstallFileGenerator::GenerateCxxModuleConfigInformation(
+ std::ostream& os) const
+{
+ // Now load per-configuration properties for them.
+ /* clang-format off */
+ os << "# Load information for each installed configuration.\n"
+ "file(GLOB _cmake_cxx_module_includes \"${CMAKE_CURRENT_LIST_DIR}/cxx-modules-*.cmake\")\n"
+ "foreach(_cmake_cxx_module_include IN LISTS _cmake_cxx_module_includes)\n"
+ " include(\"${_cmake_cxx_module_include}\")\n"
+ "endforeach()\n"
+ "unset(_cmake_cxx_module_include)\n"
+ "unset(_cmake_cxx_module_includes)\n";
+ /* clang-format on */
+}
+
+bool cmExportInstallFileGenerator::
+ GenerateImportCxxModuleConfigTargetInclusion(std::string const& config)
+{
+ auto cxx_modules_dirname = this->GetCxxModulesDirectory();
+ if (cxx_modules_dirname.empty()) {
+ return true;
+ }
+
+ std::string filename_config = config;
+ if (filename_config.empty()) {
+ filename_config = "noconfig";
+ }
+
+ std::string const dest =
+ cmStrCat(this->FileDir, '/', cxx_modules_dirname, '/');
+ std::string fileName =
+ cmStrCat(dest, "cxx-modules-", filename_config, ".cmake");
+
+ cmGeneratedFileStream os(fileName, true);
+ if (!os) {
+ std::string se = cmSystemTools::GetLastSystemError();
+ std::ostringstream e;
+ e << "cannot write to file \"" << fileName << "\": " << se;
+ cmSystemTools::Error(e.str());
+ return false;
+ }
+ os.SetCopyIfDifferent(true);
+
+ // Record this per-config import file.
+ this->ConfigCxxModuleFiles[config] = fileName;
+
+ auto& prop_files = this->ConfigCxxModuleTargetFiles[config];
+ for (auto const* tgt : this->ExportedTargets) {
+ auto prop_filename = cmStrCat("target-", tgt->GetExportName(), '-',
+ filename_config, ".cmake");
+ prop_files.emplace_back(cmStrCat(dest, prop_filename));
+ os << "include(\"${CMAKE_CURRENT_LIST_DIR}/" << prop_filename << "\")\n";
+ }
+
+ return true;
+}
diff --git a/Source/cmExportInstallFileGenerator.h b/Source/cmExportInstallFileGenerator.h
index 86fb505..e073a31 100644
--- a/Source/cmExportInstallFileGenerator.h
+++ b/Source/cmExportInstallFileGenerator.h
@@ -50,6 +50,23 @@ public:
return this->ConfigImportFiles;
}
+ /** Get the per-config C++ module file generated for each configuration.
+ This maps from the configuration name to the file temporary location
+ for installation. */
+ std::map<std::string, std::string> const& GetConfigCxxModuleFiles()
+ {
+ return this->ConfigCxxModuleFiles;
+ }
+
+ /** Get the per-config C++ module file generated for each configuration.
+ This maps from the configuration name to the file temporary location
+ for installation for each target in the export set. */
+ std::map<std::string, std::vector<std::string>> const&
+ GetConfigCxxModuleTargetFiles()
+ {
+ return this->ConfigCxxModuleTargetFiles;
+ }
+
/** Compute the globbing expression used to load per-config import
files from the main file. */
std::string GetConfigImportFileGlob();
@@ -100,8 +117,16 @@ protected:
std::string GetFileSetFiles(cmGeneratorTarget* gte, cmFileSet* fileSet,
cmTargetExport* te) override;
+ std::string GetCxxModulesDirectory() const override;
+ void GenerateCxxModuleConfigInformation(std::ostream&) const override;
+ bool GenerateImportCxxModuleConfigTargetInclusion(std::string const&);
+
cmInstallExportGenerator* IEGen;
// The import file generated for each configuration.
std::map<std::string, std::string> ConfigImportFiles;
+ // The C++ module property file generated for each configuration.
+ std::map<std::string, std::string> ConfigCxxModuleFiles;
+ // The C++ module property target files generated for each configuration.
+ std::map<std::string, std::vector<std::string>> ConfigCxxModuleTargetFiles;
};
diff --git a/Source/cmExportTryCompileFileGenerator.h b/Source/cmExportTryCompileFileGenerator.h
index 1dd8a20..5c34fad 100644
--- a/Source/cmExportTryCompileFileGenerator.h
+++ b/Source/cmExportTryCompileFileGenerator.h
@@ -55,6 +55,9 @@ protected:
std::string GetFileSetFiles(cmGeneratorTarget* target, cmFileSet* fileSet,
cmTargetExport* te) override;
+ std::string GetCxxModulesDirectory() const override { return {}; }
+ void GenerateCxxModuleConfigInformation(std::ostream&) const override {}
+
private:
std::string FindTargets(const std::string& prop,
const cmGeneratorTarget* tgt,
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index dd0540c..0581802 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -27,6 +27,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmInstallCxxModuleBmiGenerator.h"
#include "cmInstallDirectoryGenerator.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallFileSetGenerator.h"
@@ -1092,6 +1093,21 @@ Json::Value DirectoryObject::DumpInstaller(cmInstallGenerator* gen)
if (installFileSet->GetOptional()) {
installer["isOptional"] = true;
}
+ } else if (auto* cxxModuleBmi =
+ dynamic_cast<cmInstallCxxModuleBmiGenerator*>(gen)) {
+ installer["type"] = "cxxModuleBmi";
+ installer["destination"] = cxxModuleBmi->GetDestination(this->Config);
+
+ auto const* target = cxxModuleBmi->GetTarget();
+ installer["cxxModuleBmiTarget"] = Json::objectValue;
+ installer["cxxModuleBmiTarget"]["id"] = TargetId(target, this->TopBuild);
+ installer["cxxModuleBmiTarget"]["index"] = this->TargetIndexMap[target];
+
+ // FIXME: Parse FilePermissions.
+ // FIXME: Parse MessageLevel.
+ if (cxxModuleBmi->GetOptional()) {
+ installer["isOptional"] = true;
+ }
}
// Add fields common to all install generators.
diff --git a/Source/cmFileCommand.cxx b/Source/cmFileCommand.cxx
index 7d05347..7810040 100644
--- a/Source/cmFileCommand.cxx
+++ b/Source/cmFileCommand.cxx
@@ -28,8 +28,8 @@
#include "cm_sys_stat.h"
-#include "cmAlgorithms.h"
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
#include "cmCMakePath.h"
#include "cmCryptoHash.h"
#include "cmELF.h"
@@ -172,7 +172,8 @@ bool HandleReadCommand(std::vector<std::string> const& args,
.Bind("LIMIT"_s, &Arguments::Limit)
.Bind("HEX"_s, &Arguments::Hex);
- Arguments const arguments = parser.Parse(cmMakeRange(args).advance(3));
+ Arguments const arguments = parser.Parse(cmMakeRange(args).advance(3),
+ /*unparsedArguments=*/nullptr);
std::string fileName = fileNameArg;
if (!cmsys::SystemTools::FileIsFullPath(fileName)) {
@@ -953,42 +954,34 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args,
{
// Evaluate arguments.
std::string file;
- std::string oldRPath;
- std::string newRPath;
+ cm::optional<std::string> oldRPath;
+ cm::optional<std::string> newRPath;
bool removeEnvironmentRPath = false;
cmArgumentParser<void> parser;
std::vector<std::string> unknownArgs;
- std::vector<std::string> missingArgs;
- std::vector<std::string> parsedArgs;
parser.Bind("FILE"_s, file)
.Bind("OLD_RPATH"_s, oldRPath)
.Bind("NEW_RPATH"_s, newRPath)
.Bind("INSTALL_REMOVE_ENVIRONMENT_RPATH"_s, removeEnvironmentRPath);
- parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs,
- &parsedArgs);
+ ArgumentParser::ParseResult parseResult =
+ parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
if (!unknownArgs.empty()) {
status.SetError(
cmStrCat("RPATH_CHANGE given unknown argument ", unknownArgs.front()));
return false;
}
- if (!missingArgs.empty()) {
- status.SetError(cmStrCat("RPATH_CHANGE \"", missingArgs.front(),
- "\" argument not given value."));
- return false;
+ if (parseResult.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (file.empty()) {
status.SetError("RPATH_CHANGE not given FILE option.");
return false;
}
- if (oldRPath.empty() &&
- std::find(parsedArgs.begin(), parsedArgs.end(), "OLD_RPATH") ==
- parsedArgs.end()) {
+ if (!oldRPath) {
status.SetError("RPATH_CHANGE not given OLD_RPATH option.");
return false;
}
- if (newRPath.empty() &&
- std::find(parsedArgs.begin(), parsedArgs.end(), "NEW_RPATH") ==
- parsedArgs.end()) {
+ if (!newRPath) {
status.SetError("RPATH_CHANGE not given NEW_RPATH option.");
return false;
}
@@ -1002,17 +995,17 @@ bool HandleRPathChangeCommand(std::vector<std::string> const& args,
std::string emsg;
bool changed;
- if (!cmSystemTools::ChangeRPath(file, oldRPath, newRPath,
+ if (!cmSystemTools::ChangeRPath(file, *oldRPath, *newRPath,
removeEnvironmentRPath, &emsg, &changed)) {
status.SetError(cmStrCat("RPATH_CHANGE could not write new RPATH:\n ",
- newRPath, "\nto the file:\n ", file, "\n",
+ *newRPath, "\nto the file:\n ", file, "\n",
emsg));
success = false;
}
if (success) {
if (changed) {
std::string message =
- cmStrCat("Set runtime path of \"", file, "\" to \"", newRPath, '"');
+ cmStrCat("Set runtime path of \"", file, "\" to \"", *newRPath, '"');
status.GetMakefile().DisplayStatus(message, -1);
}
ft.Store(file);
@@ -1025,31 +1018,25 @@ bool HandleRPathSetCommand(std::vector<std::string> const& args,
{
// Evaluate arguments.
std::string file;
- std::string newRPath;
+ cm::optional<std::string> newRPath;
cmArgumentParser<void> parser;
std::vector<std::string> unknownArgs;
- std::vector<std::string> missingArgs;
- std::vector<std::string> parsedArgs;
parser.Bind("FILE"_s, file).Bind("NEW_RPATH"_s, newRPath);
- parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs,
- &parsedArgs);
+ ArgumentParser::ParseResult parseResult =
+ parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
if (!unknownArgs.empty()) {
status.SetError(cmStrCat("RPATH_SET given unrecognized argument \"",
unknownArgs.front(), "\"."));
return false;
}
- if (!missingArgs.empty()) {
- status.SetError(cmStrCat("RPATH_SET \"", missingArgs.front(),
- "\" argument not given value."));
- return false;
+ if (parseResult.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (file.empty()) {
status.SetError("RPATH_SET not given FILE option.");
return false;
}
- if (newRPath.empty() &&
- std::find(parsedArgs.begin(), parsedArgs.end(), "NEW_RPATH") ==
- parsedArgs.end()) {
+ if (!newRPath) {
status.SetError("RPATH_SET not given NEW_RPATH option.");
return false;
}
@@ -1063,16 +1050,16 @@ bool HandleRPathSetCommand(std::vector<std::string> const& args,
std::string emsg;
bool changed;
- if (!cmSystemTools::SetRPath(file, newRPath, &emsg, &changed)) {
+ if (!cmSystemTools::SetRPath(file, *newRPath, &emsg, &changed)) {
status.SetError(cmStrCat("RPATH_SET could not write new RPATH:\n ",
- newRPath, "\nto the file:\n ", file, "\n",
+ *newRPath, "\nto the file:\n ", file, "\n",
emsg));
success = false;
}
if (success) {
if (changed) {
std::string message =
- cmStrCat("Set runtime path of \"", file, "\" to \"", newRPath, '"');
+ cmStrCat("Set runtime path of \"", file, "\" to \"", *newRPath, '"');
status.GetMakefile().DisplayStatus(message, -1);
}
ft.Store(file);
@@ -1087,18 +1074,16 @@ bool HandleRPathRemoveCommand(std::vector<std::string> const& args,
std::string file;
cmArgumentParser<void> parser;
std::vector<std::string> unknownArgs;
- std::vector<std::string> missingArgs;
parser.Bind("FILE"_s, file);
- parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs);
+ ArgumentParser::ParseResult parseResult =
+ parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
if (!unknownArgs.empty()) {
status.SetError(
cmStrCat("RPATH_REMOVE given unknown argument ", unknownArgs.front()));
return false;
}
- if (!missingArgs.empty()) {
- status.SetError(cmStrCat("RPATH_REMOVE \"", missingArgs.front(),
- "\" argument not given value."));
- return false;
+ if (parseResult.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (file.empty()) {
status.SetError("RPATH_REMOVE not given FILE option.");
@@ -1135,31 +1120,25 @@ bool HandleRPathCheckCommand(std::vector<std::string> const& args,
{
// Evaluate arguments.
std::string file;
- std::string rpath;
+ cm::optional<std::string> rpath;
cmArgumentParser<void> parser;
std::vector<std::string> unknownArgs;
- std::vector<std::string> missingArgs;
- std::vector<std::string> parsedArgs;
parser.Bind("FILE"_s, file).Bind("RPATH"_s, rpath);
- parser.Parse(cmMakeRange(args).advance(1), &unknownArgs, &missingArgs,
- &parsedArgs);
+ ArgumentParser::ParseResult parseResult =
+ parser.Parse(cmMakeRange(args).advance(1), &unknownArgs);
if (!unknownArgs.empty()) {
status.SetError(
cmStrCat("RPATH_CHECK given unknown argument ", unknownArgs.front()));
return false;
}
- if (!missingArgs.empty()) {
- status.SetError(cmStrCat("RPATH_CHECK \"", missingArgs.front(),
- "\" argument not given value."));
- return false;
+ if (parseResult.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (file.empty()) {
status.SetError("RPATH_CHECK not given FILE option.");
return false;
}
- if (rpath.empty() &&
- std::find(parsedArgs.begin(), parsedArgs.end(), "RPATH") ==
- parsedArgs.end()) {
+ if (!rpath) {
status.SetError("RPATH_CHECK not given RPATH option.");
return false;
}
@@ -1168,7 +1147,7 @@ bool HandleRPathCheckCommand(std::vector<std::string> const& args,
// delete it. This is used during installation to re-install a file
// if its RPath will change.
if (cmSystemTools::FileExists(file, true) &&
- !cmSystemTools::CheckRPath(file, rpath)) {
+ !cmSystemTools::CheckRPath(file, *rpath)) {
cmSystemTools::RemoveFile(file);
}
@@ -1197,7 +1176,8 @@ bool HandleReadElfCommand(std::vector<std::string> const& args,
.Bind("RPATH"_s, &Arguments::RPath)
.Bind("RUNPATH"_s, &Arguments::RunPath)
.Bind("CAPTURE_ERROR"_s, &Arguments::Error);
- Arguments const arguments = parser.Parse(cmMakeRange(args).advance(2));
+ Arguments const arguments = parser.Parse(cmMakeRange(args).advance(2),
+ /*unparsedArguments=*/nullptr);
if (!cmSystemTools::FileExists(fileNameArg, true)) {
status.SetError(cmStrCat("READ_ELF given FILE \"", fileNameArg,
@@ -1250,9 +1230,9 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
return false;
}
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
- std::string BaseDirectory;
+ cm::optional<std::string> BaseDirectory;
bool ExpandTilde = false;
};
static auto const parser =
@@ -1261,22 +1241,18 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
.Bind("EXPAND_TILDE"_s, &Arguments::ExpandTilde);
std::vector<std::string> unparsedArguments;
- std::vector<std::string> keywordsMissingValue;
- std::vector<std::string> parsedKeywords;
auto arguments =
- parser.Parse(cmMakeRange(args).advance(3), &unparsedArguments,
- &keywordsMissingValue, &parsedKeywords);
+ parser.Parse(cmMakeRange(args).advance(3), &unparsedArguments);
if (!unparsedArguments.empty()) {
status.SetError("REAL_PATH called with unexpected arguments");
return false;
}
- if (!keywordsMissingValue.empty()) {
- status.SetError("BASE_DIRECTORY requires a value");
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
- if (parsedKeywords.empty()) {
+ if (!arguments.BaseDirectory) {
arguments.BaseDirectory = status.GetMakefile().GetCurrentSourceDirectory();
}
@@ -1295,7 +1271,7 @@ bool HandleRealPathCommand(std::vector<std::string> const& args,
}
cmCMakePath path(input, cmCMakePath::auto_format);
- path = path.Absolute(arguments.BaseDirectory).Normal();
+ path = path.Absolute(*arguments.BaseDirectory).Normal();
auto realPath = cmSystemTools::GetRealPath(path.GenericString());
status.GetMakefile().AddDefinition(args[2], realPath);
@@ -1938,7 +1914,7 @@ bool HandleDownloadCommand(std::vector<std::string> const& args,
std::string msg;
std::string actualHash = hash->HashFile(file);
if (actualHash == expectedHash) {
- msg = cmStrCat("returning early; file already exists with expected ",
+ msg = cmStrCat("skipping download as file already exists with expected ",
hashMatchMSG, '"');
if (!statusVar.empty()) {
status.GetMakefile().AddDefinition(statusVar, cmStrCat(0, ";\"", msg));
@@ -2495,17 +2471,18 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
return false;
}
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
- std::string Output;
- std::string Input;
- std::string Content;
- std::string Condition;
- std::string Target;
- std::string NewLineStyle;
+ cm::optional<std::string> Output;
+ cm::optional<std::string> Input;
+ cm::optional<std::string> Content;
+ cm::optional<std::string> Condition;
+ cm::optional<std::string> Target;
+ cm::optional<std::string> NewLineStyle;
bool NoSourcePermissions = false;
bool UseSourcePermissions = false;
- std::vector<std::string> FilePermissions;
+ ArgumentParser::NonEmpty<std::vector<std::string>> FilePermissions;
+ std::vector<cm::string_view> ParsedKeywords;
};
static auto const parser =
@@ -2518,18 +2495,15 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
.Bind("NO_SOURCE_PERMISSIONS"_s, &Arguments::NoSourcePermissions)
.Bind("USE_SOURCE_PERMISSIONS"_s, &Arguments::UseSourcePermissions)
.Bind("FILE_PERMISSIONS"_s, &Arguments::FilePermissions)
- .Bind("NEWLINE_STYLE"_s, &Arguments::NewLineStyle);
+ .Bind("NEWLINE_STYLE"_s, &Arguments::NewLineStyle)
+ .BindParsedKeywords(&Arguments::ParsedKeywords);
std::vector<std::string> unparsedArguments;
- std::vector<std::string> keywordsMissingValues;
- std::vector<std::string> parsedKeywords;
Arguments const arguments =
- parser.Parse(cmMakeRange(args).advance(1), &unparsedArguments,
- &keywordsMissingValues, &parsedKeywords);
+ parser.Parse(cmMakeRange(args).advance(1), &unparsedArguments);
- if (!keywordsMissingValues.empty()) {
- status.SetError("Incorrect arguments to GENERATE subcommand.");
- return false;
+ if (arguments.MaybeReportError(status.GetMakefile())) {
+ return true;
}
if (!unparsedArguments.empty()) {
@@ -2537,56 +2511,41 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
return false;
}
- bool mandatoryOptionsSpecified = false;
- if (parsedKeywords.size() > 1) {
- const bool outputOprionSpecified = parsedKeywords[0] == "OUTPUT"_s;
- const bool inputOrContentSpecified =
- parsedKeywords[1] == "INPUT"_s || parsedKeywords[1] == "CONTENT"_s;
- if (outputOprionSpecified && inputOrContentSpecified) {
- mandatoryOptionsSpecified = true;
- }
+ if (!arguments.Output || arguments.ParsedKeywords[0] != "OUTPUT"_s) {
+ status.SetError("GENERATE requires OUTPUT as first option.");
+ return false;
}
- if (!mandatoryOptionsSpecified) {
- status.SetError("Incorrect arguments to GENERATE subcommand.");
+ std::string const& output = *arguments.Output;
+
+ if (!arguments.Input && !arguments.Content) {
+ status.SetError("GENERATE requires INPUT or CONTENT option.");
return false;
}
+ const bool inputIsContent = arguments.ParsedKeywords[1] == "CONTENT"_s;
+ if (!inputIsContent && arguments.ParsedKeywords[1] == "INPUT") {
+ status.SetError("Unknown argument to GENERATE subcommand.");
+ }
+ std::string const& input =
+ inputIsContent ? *arguments.Content : *arguments.Input;
- const bool conditionOptionSpecified =
- std::find(parsedKeywords.begin(), parsedKeywords.end(), "CONDITION"_s) !=
- parsedKeywords.end();
- if (conditionOptionSpecified && arguments.Condition.empty()) {
+ if (arguments.Condition && arguments.Condition->empty()) {
status.SetError("CONDITION of sub-command GENERATE must not be empty "
"if specified.");
return false;
}
+ std::string const& condition =
+ arguments.Condition ? *arguments.Condition : std::string();
- const bool targetOptionSpecified =
- std::find(parsedKeywords.begin(), parsedKeywords.end(), "TARGET"_s) !=
- parsedKeywords.end();
- if (targetOptionSpecified && arguments.Target.empty()) {
+ if (arguments.Target && arguments.Target->empty()) {
status.SetError("TARGET of sub-command GENERATE must not be empty "
"if specified.");
return false;
}
+ std::string const& target =
+ arguments.Target ? *arguments.Target : std::string();
- const bool outputOptionSpecified =
- std::find(parsedKeywords.begin(), parsedKeywords.end(), "OUTPUT"_s) !=
- parsedKeywords.end();
- if (outputOptionSpecified && parsedKeywords[0] != "OUTPUT"_s) {
- status.SetError("Incorrect arguments to GENERATE subcommand.");
- return false;
- }
-
- const bool inputIsContent = parsedKeywords[1] != "INPUT"_s;
- if (inputIsContent && parsedKeywords[1] != "CONTENT") {
- status.SetError("Unknown argument to GENERATE subcommand.");
- }
-
- const bool newLineStyleSpecified =
- std::find(parsedKeywords.begin(), parsedKeywords.end(),
- "NEWLINE_STYLE"_s) != parsedKeywords.end();
cmNewLineStyle newLineStyle;
- if (newLineStyleSpecified) {
+ if (arguments.NewLineStyle) {
std::string errorMessage;
if (!newLineStyle.ReadFromArguments(args, errorMessage)) {
status.SetError(cmStrCat("GENERATE ", errorMessage));
@@ -2594,11 +2553,6 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
}
}
- std::string input = arguments.Input;
- if (inputIsContent) {
- input = arguments.Content;
- }
-
if (arguments.NoSourcePermissions && arguments.UseSourcePermissions) {
status.SetError("given both NO_SOURCE_PERMISSIONS and "
"USE_SOURCE_PERMISSIONS. Only one option allowed.");
@@ -2656,8 +2610,7 @@ bool HandleGenerateCommand(std::vector<std::string> const& args,
}
}
- AddEvaluationFile(input, arguments.Target, arguments.Output,
- arguments.Condition, inputIsContent,
+ AddEvaluationFile(input, target, output, condition, inputIsContent,
newLineStyle.GetCharacters(), permissions, status);
return true;
}
@@ -2836,7 +2789,11 @@ bool HandleTimestampCommand(std::vector<std::string> const& args,
unsigned int argsIndex = 1;
- const std::string& filename = args[argsIndex++];
+ std::string filename = args[argsIndex++];
+ if (!cmsys::SystemTools::FileIsFullPath(filename)) {
+ filename = cmStrCat(status.GetMakefile().GetCurrentSourceDirectory(), '/',
+ filename);
+ }
const std::string& outputVariable = args[argsIndex++];
@@ -3060,24 +3017,25 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
"\n ]])");
}
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
std::string ResolvedDependenciesVar;
std::string UnresolvedDependenciesVar;
std::string ConflictingDependenciesPrefix;
std::string RPathPrefix;
std::string BundleExecutable;
- std::vector<std::string> Executables;
- std::vector<std::string> Libraries;
- std::vector<std::string> Directories;
- std::vector<std::string> Modules;
- std::vector<std::string> PreIncludeRegexes;
- std::vector<std::string> PreExcludeRegexes;
- std::vector<std::string> PostIncludeRegexes;
- std::vector<std::string> PostExcludeRegexes;
- std::vector<std::string> PostIncludeFiles;
- std::vector<std::string> PostExcludeFiles;
- std::vector<std::string> PostExcludeFilesStrict;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Executables;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Libraries;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Directories;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Modules;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PreIncludeRegexes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PreExcludeRegexes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeRegexes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeRegexes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeFiles;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeFiles;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>>
+ PostExcludeFilesStrict;
};
static auto const parser =
@@ -3102,10 +3060,8 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
.Bind("POST_EXCLUDE_FILES_STRICT"_s, &Arguments::PostExcludeFilesStrict);
std::vector<std::string> unrecognizedArguments;
- std::vector<std::string> keywordsMissingValues;
auto parsedArgs =
- parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
- &keywordsMissingValues);
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
auto argIt = unrecognizedArguments.begin();
if (argIt != unrecognizedArguments.end()) {
status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
@@ -3113,26 +3069,9 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
return false;
}
- const std::vector<std::string> LIST_ARGS = {
- "DIRECTORIES",
- "EXECUTABLES",
- "LIBRARIES",
- "MODULES",
- "POST_EXCLUDE_FILES",
- "POST_EXCLUDE_FILES_STRICT",
- "POST_EXCLUDE_REGEXES",
- "POST_INCLUDE_FILES",
- "POST_INCLUDE_REGEXES",
- "PRE_EXCLUDE_REGEXES",
- "PRE_INCLUDE_REGEXES",
- };
- auto kwbegin = keywordsMissingValues.cbegin();
- auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
- if (kwend != kwbegin) {
- status.SetError(cmStrCat("Keywords missing values:\n ",
- cmJoin(cmMakeRange(kwbegin, kwend), "\n ")));
+ if (parsedArgs.MaybeReportError(status.GetMakefile())) {
cmSystemTools::SetFatalErrorOccurred();
- return false;
+ return true;
}
cmRuntimeDependencyArchive archive(
@@ -3232,13 +3171,14 @@ bool HandleGetRuntimeDependenciesCommand(std::vector<std::string> const& args,
bool HandleConfigureCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
- std::string Output;
- std::string Content;
+ cm::optional<std::string> Output;
+ cm::optional<std::string> Content;
bool EscapeQuotes = false;
bool AtOnly = false;
- std::string NewlineStyle;
+ // "NEWLINE_STYLE" requires one value, but we use a custom check below.
+ ArgumentParser::Maybe<std::string> NewlineStyle;
};
static auto const parser =
@@ -3250,11 +3190,8 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
.Bind("NEWLINE_STYLE"_s, &Arguments::NewlineStyle);
std::vector<std::string> unrecognizedArguments;
- std::vector<std::string> keywordsMissingArguments;
- std::vector<std::string> parsedKeywords;
auto parsedArgs =
- parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
- &keywordsMissingArguments, &parsedKeywords);
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
auto argIt = unrecognizedArguments.begin();
if (argIt != unrecognizedArguments.end()) {
@@ -3264,28 +3201,20 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
return false;
}
- std::vector<std::string> mandatoryOptions{ "OUTPUT", "CONTENT" };
- for (auto const& e : mandatoryOptions) {
- const bool optionHasNoValue =
- std::find(keywordsMissingArguments.begin(),
- keywordsMissingArguments.end(),
- e) != keywordsMissingArguments.end();
- if (optionHasNoValue) {
- status.SetError(cmStrCat("CONFIGURE ", e, " option needs a value."));
- cmSystemTools::SetFatalErrorOccurred();
- return false;
- }
+ if (parsedArgs.MaybeReportError(status.GetMakefile())) {
+ cmSystemTools::SetFatalErrorOccurred();
+ return true;
}
- for (auto const& e : mandatoryOptions) {
- const bool optionGiven =
- std::find(parsedKeywords.begin(), parsedKeywords.end(), e) !=
- parsedKeywords.end();
- if (!optionGiven) {
- status.SetError(cmStrCat("CONFIGURE ", e, " option is mandatory."));
- cmSystemTools::SetFatalErrorOccurred();
- return false;
- }
+ if (!parsedArgs.Output) {
+ status.SetError("CONFIGURE OUTPUT option is mandatory.");
+ cmSystemTools::SetFatalErrorOccurred();
+ return false;
+ }
+ if (!parsedArgs.Content) {
+ status.SetError("CONFIGURE CONTENT option is mandatory.");
+ cmSystemTools::SetFatalErrorOccurred();
+ return false;
}
std::string errorMessage;
@@ -3297,7 +3226,7 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
// Check for generator expressions
std::string outputFile = cmSystemTools::CollapseFullPath(
- parsedArgs.Output, status.GetMakefile().GetCurrentBinaryDirectory());
+ *parsedArgs.Output, status.GetMakefile().GetCurrentBinaryDirectory());
std::string::size_type pos = outputFile.find_first_of("<>");
if (pos != std::string::npos) {
@@ -3346,7 +3275,7 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
fout.SetCopyIfDifferent(true);
// copy input to output and expand variables from input at the same time
- std::stringstream sin(parsedArgs.Content, std::ios::in);
+ std::stringstream sin(*parsedArgs.Content, std::ios::in);
std::string inLine;
std::string outLine;
bool hasNewLine = false;
@@ -3369,15 +3298,19 @@ bool HandleConfigureCommand(std::vector<std::string> const& args,
bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
std::string Output;
std::string Format;
std::string Compression;
std::string CompressionLevel;
- std::string MTime;
+ // "MTIME" should require one value, but it has long been accidentally
+ // accepted without one and treated as if an empty value were given.
+ // Fixing this would require a policy.
+ ArgumentParser::Maybe<std::string> MTime;
bool Verbose = false;
- std::vector<std::string> Paths;
+ // "PATHS" requires at least one value, but use a custom check below.
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Paths;
};
static auto const parser =
@@ -3391,10 +3324,8 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
.Bind("PATHS"_s, &Arguments::Paths);
std::vector<std::string> unrecognizedArguments;
- std::vector<std::string> keywordsMissingValues;
auto parsedArgs =
- parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
- &keywordsMissingValues);
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
auto argIt = unrecognizedArguments.begin();
if (argIt != unrecognizedArguments.end()) {
status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
@@ -3402,16 +3333,9 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
return false;
}
- const std::vector<std::string> LIST_ARGS = {
- "OUTPUT", "FORMAT", "COMPRESSION", "COMPRESSION_LEVEL", "MTIME", "PATHS"
- };
- auto kwbegin = keywordsMissingValues.cbegin();
- auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
- if (kwend != kwbegin) {
- status.SetError(cmStrCat("Keywords missing values:\n ",
- cmJoin(cmMakeRange(kwbegin, kwend), "\n ")));
+ if (parsedArgs.MaybeReportError(status.GetMakefile())) {
cmSystemTools::SetFatalErrorOccurred();
- return false;
+ return true;
}
const char* knownFormats[] = {
@@ -3500,13 +3424,13 @@ bool HandleArchiveCreateCommand(std::vector<std::string> const& args,
bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
std::string Input;
bool Verbose = false;
bool ListOnly = false;
std::string Destination;
- std::vector<std::string> Patterns;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Patterns;
bool Touch = false;
};
@@ -3519,10 +3443,8 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
.Bind("TOUCH"_s, &Arguments::Touch);
std::vector<std::string> unrecognizedArguments;
- std::vector<std::string> keywordsMissingValues;
auto parsedArgs =
- parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments,
- &keywordsMissingValues);
+ parser.Parse(cmMakeRange(args).advance(1), &unrecognizedArguments);
auto argIt = unrecognizedArguments.begin();
if (argIt != unrecognizedArguments.end()) {
status.SetError(cmStrCat("Unrecognized argument: \"", *argIt, "\""));
@@ -3530,15 +3452,9 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
return false;
}
- const std::vector<std::string> LIST_ARGS = { "INPUT", "DESTINATION",
- "PATTERNS" };
- auto kwbegin = keywordsMissingValues.cbegin();
- auto kwend = cmRemoveMatching(keywordsMissingValues, LIST_ARGS);
- if (kwend != kwbegin) {
- status.SetError(cmStrCat("Keywords missing values:\n ",
- cmJoin(cmMakeRange(kwbegin, kwend), "\n ")));
+ if (parsedArgs.MaybeReportError(status.GetMakefile())) {
cmSystemTools::SetFatalErrorOccurred();
- return false;
+ return true;
}
std::string inFile = parsedArgs.Input;
@@ -3593,10 +3509,15 @@ bool HandleArchiveExtractCommand(std::vector<std::string> const& args,
return true;
}
-bool ValidateAndConvertPermissions(const std::vector<std::string>& permissions,
- mode_t& perms, cmExecutionStatus& status)
+bool ValidateAndConvertPermissions(
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> const&
+ permissions,
+ mode_t& perms, cmExecutionStatus& status)
{
- for (const auto& i : permissions) {
+ if (!permissions) {
+ return true;
+ }
+ for (const auto& i : *permissions) {
if (!cmFSPermissions::stringToModeT(i, perms)) {
status.SetError(i + " is an invalid permission specifier");
cmSystemTools::SetFatalErrorOccurred();
@@ -3628,11 +3549,14 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
globber.SetRecurse(recurse);
globber.SetRecurseListDirs(recurse);
- struct Arguments
+ struct Arguments : public ArgumentParser::ParseResult
{
- std::vector<std::string> Permissions;
- std::vector<std::string> FilePermissions;
- std::vector<std::string> DirectoryPermissions;
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ Permissions;
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ FilePermissions;
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>>
+ DirectoryPermissions;
};
static auto const parser =
@@ -3642,21 +3566,20 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
.Bind("DIRECTORY_PERMISSIONS"_s, &Arguments::DirectoryPermissions);
std::vector<std::string> pathEntries;
- std::vector<std::string> keywordsMissingValues;
- Arguments parsedArgs = parser.Parse(cmMakeRange(args).advance(1),
- &pathEntries, &keywordsMissingValues);
+ Arguments parsedArgs =
+ parser.Parse(cmMakeRange(args).advance(1), &pathEntries);
// check validity of arguments
- if (parsedArgs.Permissions.empty() && parsedArgs.FilePermissions.empty() &&
- parsedArgs.DirectoryPermissions.empty()) // no permissions given
+ if (!parsedArgs.Permissions && !parsedArgs.FilePermissions &&
+ !parsedArgs.DirectoryPermissions) // no permissions given
{
status.SetError("No permissions given");
cmSystemTools::SetFatalErrorOccurred();
return false;
}
- if (!parsedArgs.Permissions.empty() && !parsedArgs.FilePermissions.empty() &&
- !parsedArgs.DirectoryPermissions.empty()) // all keywords are used
+ if (parsedArgs.Permissions && parsedArgs.FilePermissions &&
+ parsedArgs.DirectoryPermissions) // all keywords are used
{
status.SetError("Remove either PERMISSIONS or FILE_PERMISSIONS or "
"DIRECTORY_PERMISSIONS from the invocation");
@@ -3664,12 +3587,9 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
return false;
}
- if (!keywordsMissingValues.empty()) {
- for (const auto& i : keywordsMissingValues) {
- status.SetError(i + " is not given any arguments");
- cmSystemTools::SetFatalErrorOccurred();
- }
- return false;
+ if (parsedArgs.MaybeReportError(status.GetMakefile())) {
+ cmSystemTools::SetFatalErrorOccurred();
+ return true;
}
// validate permissions
@@ -3713,7 +3633,7 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
if (cmSystemTools::FileExists(i, true)) {
bool success = true;
const mode_t& filePermissions =
- parsedArgs.FilePermissions.empty() ? perms : fperms;
+ parsedArgs.FilePermissions ? fperms : perms;
if (filePermissions) {
success = SetPermissions(i, filePermissions, status);
}
@@ -3725,7 +3645,7 @@ bool HandleChmodCommandImpl(std::vector<std::string> const& args, bool recurse,
else if (cmSystemTools::FileIsDirectory(i)) {
bool success = true;
const mode_t& directoryPermissions =
- parsedArgs.DirectoryPermissions.empty() ? perms : dperms;
+ parsedArgs.DirectoryPermissions ? dperms : perms;
if (directoryPermissions) {
success = SetPermissions(i, directoryPermissions, status);
}
diff --git a/Source/cmFindBase.cxx b/Source/cmFindBase.cxx
index 1da995a..b8d345f 100644
--- a/Source/cmFindBase.cxx
+++ b/Source/cmFindBase.cxx
@@ -2,15 +2,20 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmFindBase.h"
+#include <algorithm>
#include <cstddef>
#include <deque>
+#include <functional>
#include <map>
#include <utility>
#include <cm/optional>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include "cmCMakePath.h"
+#include "cmExecutionStatus.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -24,8 +29,6 @@
#include "cmWindowsRegistry.h"
#include "cmake.h"
-class cmExecutionStatus;
-
cmFindBase::cmFindBase(std::string findCommandName, cmExecutionStatus& status)
: cmFindCommon(status)
, FindCommandName(std::move(findCommandName))
@@ -138,6 +141,31 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
cmStrCat("given invalid value for \"REGISTRY_VIEW\": ", args[j]));
return false;
}
+ } else if (args[j] == "VALIDATOR") {
+ if (++j == args.size()) {
+ this->SetError("missing required argument for \"VALIDATOR\"");
+ return false;
+ }
+ auto command = this->Makefile->GetState()->GetCommand(args[j]);
+ if (command == nullptr) {
+ this->SetError(cmStrCat(
+ "command specified for \"VALIDATOR\" is undefined: ", args[j], '.'));
+ return false;
+ }
+ // ensure a macro is not specified as validator
+ const auto& validatorName = args[j];
+ auto macros = cmExpandedList(this->Makefile->GetProperty("MACROS"));
+ if (std::find_if(macros.begin(), macros.end(),
+ [&validatorName](const std::string& item) {
+ return cmSystemTools::Strucmp(validatorName.c_str(),
+ item.c_str()) == 0;
+ }) != macros.end()) {
+ this->SetError(cmStrCat(
+ "command specified for \"VALIDATOR\" is not a function: ", args[j],
+ '.'));
+ return false;
+ }
+ this->ValidatorName = args[j];
} else if (this->CheckCommonArgument(args[j])) {
doing = DoingNone;
} else {
@@ -188,6 +216,36 @@ bool cmFindBase::ParseArguments(std::vector<std::string> const& argsIn)
return true;
}
+bool cmFindBase::Validate(const std::string& path) const
+{
+ if (this->ValidatorName.empty()) {
+ return true;
+ }
+
+ // The validator command will be executed in an isolated scope.
+ cmMakefile::ScopePushPop varScope(this->Makefile);
+ cmMakefile::PolicyPushPop polScope(this->Makefile);
+ static_cast<void>(varScope);
+ static_cast<void>(polScope);
+
+ auto resultName =
+ cmStrCat("CMAKE_"_s, cmSystemTools::UpperCase(this->FindCommandName),
+ "_VALIDATOR_STATUS"_s);
+
+ this->Makefile->AddDefinitionBool(resultName, true);
+
+ cmListFileFunction validator(
+ this->ValidatorName, 0, 0,
+ { cmListFileArgument(resultName, cmListFileArgument::Unquoted, 0),
+ cmListFileArgument(path, cmListFileArgument::Quoted, 0) });
+ cmExecutionStatus status(*this->Makefile);
+
+ if (this->Makefile->ExecuteCommand(validator, status)) {
+ return this->Makefile->GetDefinition(resultName).IsOn();
+ }
+ return false;
+}
+
void cmFindBase::ExpandPaths()
{
if (!this->NoDefaultPath) {
diff --git a/Source/cmFindBase.h b/Source/cmFindBase.h
index d197424..75d9a6d 100644
--- a/Source/cmFindBase.h
+++ b/Source/cmFindBase.h
@@ -31,6 +31,11 @@ public:
*/
virtual bool ParseArguments(std::vector<std::string> const& args);
+ /**
+ * To check validity of a found path using user's validator, if any
+ */
+ bool Validate(const std::string& path) const;
+
protected:
friend class cmFindBaseDebugState;
void ExpandPaths();
@@ -63,6 +68,8 @@ protected:
bool Required = false;
+ std::string ValidatorName;
+
private:
// Add pieces of the search.
void FillPackageRootPath();
diff --git a/Source/cmFindLibraryCommand.cxx b/Source/cmFindLibraryCommand.cxx
index 1c4039b..6296a60 100644
--- a/Source/cmFindLibraryCommand.cxx
+++ b/Source/cmFindLibraryCommand.cxx
@@ -192,6 +192,7 @@ struct cmFindLibraryHelper
// Context information.
cmMakefile* Makefile;
+ cmFindBase const* FindBase;
cmGlobalGenerator* GG;
// List of valid prefixes and suffixes.
@@ -239,6 +240,11 @@ struct cmFindLibraryHelper
bool CheckDirectory(std::string const& path);
bool CheckDirectoryForName(std::string const& path, Name& name);
+ bool Validate(const std::string& path) const
+ {
+ return this->FindBase->Validate(path);
+ }
+
cmFindBaseDebugState DebugSearches;
void DebugLibraryFailed(std::string const& name, std::string const& path)
@@ -291,6 +297,7 @@ std::string const& get_suffixes(cmMakefile* mf)
cmFindLibraryHelper::cmFindLibraryHelper(std::string debugName, cmMakefile* mf,
cmFindBase const* base)
: Makefile(mf)
+ , FindBase(base)
, DebugMode(base->DebugModeEnabled())
, DebugSearches(std::move(debugName), base)
{
@@ -416,10 +423,13 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
if (!exists) {
this->DebugLibraryFailed(name.Raw, path);
} else {
- this->DebugLibraryFound(name.Raw, path);
- this->BestPath = cmSystemTools::CollapseFullPath(this->TestPath);
- cmSystemTools::ConvertToUnixSlashes(this->BestPath);
- return true;
+ auto testPath = cmSystemTools::CollapseFullPath(this->TestPath);
+ if (this->Validate(testPath)) {
+ this->DebugLibraryFound(name.Raw, path);
+ this->BestPath = testPath;
+ return true;
+ }
+ this->DebugLibraryFailed(name.Raw, path);
}
}
@@ -443,8 +453,11 @@ bool cmFindLibraryHelper::CheckDirectoryForName(std::string const& path,
this->TestPath = cmStrCat(path, origName);
// Make sure the path is readable and is not a directory.
if (cmSystemTools::FileExists(this->TestPath, true)) {
- this->DebugLibraryFound(name.Raw, dir);
+ if (!this->Validate(cmSystemTools::CollapseFullPath(this->TestPath))) {
+ continue;
+ }
+ this->DebugLibraryFound(name.Raw, dir);
// This is a matching file. Check if it is better than the
// best name found so far. Earlier prefixes are preferred,
// followed by earlier suffixes. For OpenBSD, shared library
@@ -541,7 +554,10 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryNamesPerDir()
for (std::string const& n : this->Names) {
fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
- return cmSystemTools::CollapseFullPath(fwPath);
+ auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+ if (this->Validate(finalPath)) {
+ return finalPath;
+ }
}
}
}
@@ -558,7 +574,10 @@ std::string cmFindLibraryCommand::FindFrameworkLibraryDirsPerName()
for (std::string const& d : this->SearchPaths) {
fwPath = cmStrCat(d, n, ".framework");
if (cmSystemTools::FileIsDirectory(fwPath)) {
- return cmSystemTools::CollapseFullPath(fwPath);
+ auto finalPath = cmSystemTools::CollapseFullPath(fwPath);
+ if (this->Validate(finalPath)) {
+ return finalPath;
+ }
}
}
}
diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx
index 8c6a0aa..3f8378b 100644
--- a/Source/cmFindPackageCommand.cxx
+++ b/Source/cmFindPackageCommand.cxx
@@ -5,7 +5,6 @@
#include <algorithm>
#include <cassert>
#include <cstdio>
-#include <cstring>
#include <deque>
#include <functional>
#include <iterator>
@@ -43,8 +42,405 @@
# include <StorageDefs.h>
#endif
+#if defined(_WIN32) && !defined(__CYGWIN__)
+# include <windows.h>
+// http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx
+# if !defined(KEY_WOW64_32KEY)
+# define KEY_WOW64_32KEY 0x0200
+# endif
+# if !defined(KEY_WOW64_64KEY)
+# define KEY_WOW64_64KEY 0x0100
+# endif
+#endif
+
class cmExecutionStatus;
-class cmFileList;
+
+namespace {
+
+template <template <typename> class Op>
+struct StrverscmpOp
+{
+ bool operator()(const std::string& lhs, const std::string& rhs) const
+ {
+ return Op<int>()(cmSystemTools::strverscmp(lhs, rhs), 0);
+ }
+};
+
+std::size_t collectPathsForDebug(std::string& buffer,
+ cmSearchPath const& searchPath,
+ std::size_t const startIndex = 0)
+{
+ const auto& paths = searchPath.GetPaths();
+ if (paths.empty()) {
+ buffer += " none\n";
+ return 0;
+ }
+ for (auto i = startIndex; i < paths.size(); i++) {
+ buffer += " " + paths[i].Path + "\n";
+ }
+ return paths.size();
+}
+
+#if !(defined(_WIN32) && !defined(__CYGWIN__))
+class cmFindPackageCommandHoldFile
+{
+ const char* File;
+
+public:
+ cmFindPackageCommandHoldFile(const char* const f)
+ : File(f)
+ {
+ }
+ ~cmFindPackageCommandHoldFile()
+ {
+ if (this->File) {
+ cmSystemTools::RemoveFile(this->File);
+ }
+ }
+ cmFindPackageCommandHoldFile(const cmFindPackageCommandHoldFile&) = delete;
+ cmFindPackageCommandHoldFile& operator=(
+ const cmFindPackageCommandHoldFile&) = delete;
+ void Release() { this->File = nullptr; }
+};
+#endif
+
+bool isDirentryToIgnore(const char* const fname)
+{
+ assert(fname != nullptr);
+ assert(fname[0] != 0);
+ return fname[0] == '.' &&
+ (fname[1] == 0 || (fname[1] == '.' && fname[2] == 0));
+}
+
+class cmAppendPathSegmentGenerator
+{
+public:
+ cmAppendPathSegmentGenerator(cm::string_view dirName)
+ : DirName{ dirName }
+ {
+ }
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ if (this->NeedReset) {
+ return {};
+ }
+ this->NeedReset = true;
+ return cmStrCat(parent, '/', this->DirName);
+ }
+
+ void Reset() { this->NeedReset = false; }
+
+private:
+ const cm::string_view DirName;
+ bool NeedReset = false;
+};
+
+class cmEnumPathSegmentsGenerator
+{
+public:
+ cmEnumPathSegmentsGenerator(const std::vector<cm::string_view>& init)
+ : Names{ init }
+ , Current{ this->Names.get().cbegin() }
+ {
+ }
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ if (this->Current != this->Names.get().cend()) {
+ return cmStrCat(parent, '/', *this->Current++);
+ }
+ return {};
+ }
+
+ void Reset() { this->Current = this->Names.get().cbegin(); }
+
+private:
+ std::reference_wrapper<const std::vector<cm::string_view>> Names;
+ std::vector<cm::string_view>::const_iterator Current;
+};
+
+class cmCaseInsensitiveDirectoryListGenerator
+{
+public:
+ cmCaseInsensitiveDirectoryListGenerator(cm::string_view name)
+ : DirectoryLister{}
+ , DirName{ name }
+ {
+ }
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ if (!this->Loaded) {
+ this->CurrentIdx = 0ul;
+ this->Loaded = true;
+ if (!this->DirectoryLister.Load(parent)) {
+ return {};
+ }
+ }
+
+ while (this->CurrentIdx < this->DirectoryLister.GetNumberOfFiles()) {
+ const char* const fname =
+ this->DirectoryLister.GetFile(this->CurrentIdx++);
+ if (isDirentryToIgnore(fname)) {
+ continue;
+ }
+ if (cmsysString_strcasecmp(fname, this->DirName.data()) == 0) {
+ auto candidate = cmStrCat(parent, '/', fname);
+ if (cmSystemTools::FileIsDirectory(candidate)) {
+ return candidate;
+ }
+ }
+ }
+ return {};
+ }
+
+ void Reset() { this->Loaded = false; }
+
+private:
+ cmsys::Directory DirectoryLister;
+ const cm::string_view DirName;
+ unsigned long CurrentIdx = 0ul;
+ bool Loaded = false;
+};
+
+class cmDirectoryListGenerator
+{
+public:
+ cmDirectoryListGenerator(std::vector<std::string> const& names)
+ : Names{ names }
+ , Matches{}
+ , Current{ this->Matches.cbegin() }
+ {
+ }
+ virtual ~cmDirectoryListGenerator() = default;
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ // Construct a list of matches if not yet
+ if (this->Matches.empty()) {
+ cmsys::Directory directoryLister;
+ // ALERT `Directory::Load()` keeps only names
+ // internally and LOST entry type from `dirent`.
+ // So, `Directory::FileIsDirectory` gonna use
+ // `SystemTools::FileIsDirectory()` and waste a syscall.
+ // TODO Need to enhance the `Directory` class.
+ directoryLister.Load(parent);
+
+ // ATTENTION Is it guaranteed that first two entries are
+ // `.` and `..`?
+ // TODO If so, just start with index 2 and drop the
+ // `isDirentryToIgnore(i)` condition to check.
+ for (auto i = 0ul; i < directoryLister.GetNumberOfFiles(); ++i) {
+ const char* const fname = directoryLister.GetFile(i);
+ if (isDirentryToIgnore(fname)) {
+ continue;
+ }
+
+ for (const auto& n : this->Names.get()) {
+ // NOTE Customization point for `cmMacProjectDirectoryListGenerator`
+ const auto name = this->TransformNameBeforeCmp(n);
+ // Skip entries that don't match and non-directories.
+ // ATTENTION BTW, original code also didn't check if it's a symlink
+ // to a directory!
+ const auto equal =
+ (cmsysString_strncasecmp(fname, name.c_str(), name.length()) == 0);
+ if (equal && directoryLister.FileIsDirectory(i)) {
+ this->Matches.emplace_back(fname);
+ }
+ }
+ }
+ // NOTE Customization point for `cmProjectDirectoryListGenerator`
+ this->OnMatchesLoaded();
+
+ this->Current = this->Matches.cbegin();
+ }
+
+ if (this->Current != this->Matches.cend()) {
+ auto candidate = cmStrCat(parent, '/', *this->Current++);
+ return candidate;
+ }
+
+ return {};
+ }
+
+ void Reset()
+ {
+ this->Matches.clear();
+ this->Current = this->Matches.cbegin();
+ }
+
+protected:
+ virtual void OnMatchesLoaded() {}
+ virtual std::string TransformNameBeforeCmp(std::string same) { return same; }
+
+ std::reference_wrapper<const std::vector<std::string>> Names;
+ std::vector<std::string> Matches;
+ std::vector<std::string>::const_iterator Current;
+};
+
+class cmProjectDirectoryListGenerator : public cmDirectoryListGenerator
+{
+public:
+ cmProjectDirectoryListGenerator(std::vector<std::string> const& names,
+ cmFindPackageCommand::SortOrderType so,
+ cmFindPackageCommand::SortDirectionType sd)
+ : cmDirectoryListGenerator{ names }
+ , SortOrder{ so }
+ , SortDirection{ sd }
+ {
+ }
+
+protected:
+ void OnMatchesLoaded() override
+ {
+ // check if there is a specific sorting order to perform
+ if (this->SortOrder != cmFindPackageCommand::None) {
+ cmFindPackageCommand::Sort(this->Matches.begin(), this->Matches.end(),
+ this->SortOrder, this->SortDirection);
+ }
+ }
+
+private:
+ // sort parameters
+ const cmFindPackageCommand::SortOrderType SortOrder;
+ const cmFindPackageCommand::SortDirectionType SortDirection;
+};
+
+class cmMacProjectDirectoryListGenerator : public cmDirectoryListGenerator
+{
+public:
+ cmMacProjectDirectoryListGenerator(const std::vector<std::string>& names,
+ cm::string_view ext)
+ : cmDirectoryListGenerator{ names }
+ , Extension{ ext }
+ {
+ }
+
+protected:
+ std::string TransformNameBeforeCmp(std::string name) override
+ {
+ return cmStrCat(name, this->Extension);
+ }
+
+private:
+ const cm::string_view Extension;
+};
+
+class cmFileListGeneratorGlob
+{
+public:
+ cmFileListGeneratorGlob(cm::string_view pattern)
+ : Pattern(pattern)
+ , Files{}
+ , Current{}
+ {
+ }
+
+ std::string GetNextCandidate(const std::string& parent)
+ {
+ if (this->Files.empty()) {
+ // Glob the set of matching files.
+ std::string expr = cmStrCat(parent, this->Pattern);
+ cmsys::Glob g;
+ if (!g.FindFiles(expr)) {
+ return {};
+ }
+ this->Files = g.GetFiles();
+ this->Current = this->Files.cbegin();
+ }
+
+ // Skip non-directories
+ for (; this->Current != this->Files.cend() &&
+ !cmSystemTools::FileIsDirectory(*this->Current);
+ ++this->Current) {
+ }
+
+ return (this->Current != this->Files.cend()) ? *this->Current++
+ : std::string{};
+ }
+
+ void Reset()
+ {
+ this->Files.clear();
+ this->Current = this->Files.cbegin();
+ }
+
+private:
+ cm::string_view Pattern;
+ std::vector<std::string> Files;
+ std::vector<std::string>::const_iterator Current;
+};
+
+#if defined(__LCC__)
+# define CM_LCC_DIAG_SUPPRESS_1222
+# pragma diag_suppress 1222 // invalid error number (3288, but works anyway)
+# define CM_LCC_DIAG_SUPPRESS_3288
+# pragma diag_suppress 3288 // parameter was declared but never referenced
+#endif
+
+void ResetGenerator()
+{
+}
+
+template <typename Generator>
+void ResetGenerator(Generator&& generator)
+{
+ std::forward<Generator&&>(generator).Reset();
+}
+
+template <typename Generator, typename... Generators>
+void ResetGenerator(Generator&& generator, Generators&&... generators)
+{
+ ResetGenerator(std::forward<Generator&&>(generator));
+ ResetGenerator(std::forward<Generators&&>(generators)...);
+}
+
+template <typename CallbackFn>
+bool TryGeneratedPaths(CallbackFn&& filesCollector,
+ const std::string& fullPath)
+{
+ assert(!fullPath.empty() && fullPath.back() != '/');
+ return std::forward<CallbackFn&&>(filesCollector)(fullPath + '/');
+}
+
+template <typename CallbackFn, typename Generator, typename... Rest>
+bool TryGeneratedPaths(CallbackFn&& filesCollector,
+ const std::string& startPath, Generator&& gen,
+ Rest&&... tail)
+{
+ ResetGenerator(std::forward<Generator&&>(gen));
+ for (auto path = gen.GetNextCandidate(startPath); !path.empty();
+ path = gen.GetNextCandidate(startPath)) {
+ ResetGenerator(std::forward<Rest&&>(tail)...);
+ if (TryGeneratedPaths(std::forward<CallbackFn&&>(filesCollector), path,
+ std::forward<Rest&&>(tail)...)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+#ifdef CM_LCC_DIAG_SUPPRESS_3288
+# undef CM_LCC_DIAG_SUPPRESS_3288
+# pragma diag_default 3288
+#endif
+
+#ifdef CM_LCC_DIAG_SUPPRESS_1222
+# undef CM_LCC_DIAG_SUPPRESS_1222
+# pragma diag_default 1222
+#endif
+
+// Parse the version number and store the results that were
+// successfully parsed.
+int parseVersion(const std::string& version, unsigned int& major,
+ unsigned int& minor, unsigned int& patch, unsigned int& tweak)
+{
+ return std::sscanf(version.c_str(), "%u.%u.%u.%u", &major, &minor, &patch,
+ &tweak);
+}
+
+} // anonymous namespace
cmFindPackageCommand::PathLabel
cmFindPackageCommand::PathLabel::PackageRedirect("PACKAGE_REDIRECT");
@@ -60,25 +456,10 @@ const cm::string_view cmFindPackageCommand::VERSION_ENDPOINT_INCLUDED(
const cm::string_view cmFindPackageCommand::VERSION_ENDPOINT_EXCLUDED(
"EXCLUDE");
-struct StrverscmpGreater
-{
- bool operator()(const std::string& lhs, const std::string& rhs) const
- {
- return cmSystemTools::strverscmp(lhs, rhs) > 0;
- }
-};
-
-struct StrverscmpLesser
-{
- bool operator()(const std::string& lhs, const std::string& rhs) const
- {
- return cmSystemTools::strverscmp(lhs, rhs) < 0;
- }
-};
-
void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin,
std::vector<std::string>::iterator end,
- SortOrderType order, SortDirectionType dir)
+ SortOrderType const order,
+ SortDirectionType const dir)
{
if (order == Name_order) {
if (dir == Dec) {
@@ -86,14 +467,13 @@ void cmFindPackageCommand::Sort(std::vector<std::string>::iterator begin,
} else {
std::sort(begin, end);
}
- } else if (order == Natural)
- // natural order uses letters and numbers (contiguous numbers digit are
- // compared such that e.g. 000 00 < 01 < 010 < 09 < 0 < 1 < 9 < 10
- {
+ } else if (order == Natural) {
+ // natural order uses letters and numbers (contiguous numbers digit are
+ // compared such that e.g. 000 00 < 01 < 010 < 09 < 0 < 1 < 9 < 10
if (dir == Dec) {
- std::sort(begin, end, StrverscmpGreater());
+ std::sort(begin, end, StrverscmpOp<std::greater>());
} else {
- std::sort(begin, end, StrverscmpLesser());
+ std::sort(begin, end, StrverscmpOp<std::less>());
}
}
// else do not sort
@@ -113,11 +493,10 @@ cmFindPackageCommand::cmFindPackageCommand(cmExecutionStatus& status)
void cmFindPackageCommand::AppendSearchPathGroups()
{
- std::vector<cmFindCommon::PathLabel>* labels;
-
// Update the All group with new paths. Note that package redirection must
// take precedence over everything else, so it has to be first in the array.
- labels = &this->PathGroupLabelMap[PathGroup::All];
+ std::vector<cmFindCommon::PathLabel>* const labels =
+ &this->PathGroupLabelMap[PathGroup::All];
labels->insert(labels->begin(), PathLabel::PackageRedirect);
labels->insert(
std::find(labels->begin(), labels->end(), PathLabel::CMakeSystem),
@@ -147,15 +526,15 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
// Lookup required version of CMake.
- if (cmValue rv =
+ if (cmValue const rv =
this->Makefile->GetDefinition("CMAKE_MINIMUM_REQUIRED_VERSION")) {
unsigned int v[3] = { 0, 0, 0 };
- sscanf(rv->c_str(), "%u.%u.%u", &v[0], &v[1], &v[2]);
+ std::sscanf(rv->c_str(), "%u.%u.%u", &v[0], &v[1], &v[2]);
this->RequiredCMakeVersion = CMake_VERSION_ENCODE(v[0], v[1], v[2]);
}
// Lookup target architecture, if any.
- if (cmValue arch =
+ if (cmValue const arch =
this->Makefile->GetDefinition("CMAKE_LIBRARY_ARCHITECTURE")) {
this->LibraryArchitecture = *arch;
}
@@ -184,7 +563,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// Check if User Package Registry should be disabled
// The `CMAKE_FIND_USE_PACKAGE_REGISTRY` has
// priority over the deprecated CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY
- if (cmValue def =
+ if (cmValue const def =
this->Makefile->GetDefinition("CMAKE_FIND_USE_PACKAGE_REGISTRY")) {
this->NoUserRegistry = !cmIsOn(*def);
} else if (this->Makefile->IsOn("CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY")) {
@@ -194,7 +573,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// Check if System Package Registry should be disabled
// The `CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY` has
// priority over the deprecated CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY
- if (cmValue def = this->Makefile->GetDefinition(
+ if (cmValue const def = this->Makefile->GetDefinition(
"CMAKE_FIND_USE_SYSTEM_PACKAGE_REGISTRY")) {
this->NoSystemRegistry = !cmIsOn(*def);
} else if (this->Makefile->IsOn(
@@ -208,7 +587,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
// Check if Sorting should be enabled
- if (cmValue so =
+ if (cmValue const so =
this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_ORDER")) {
if (*so == "NAME") {
@@ -219,7 +598,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->SortOrder = None;
}
}
- if (cmValue sd =
+ if (cmValue const sd =
this->Makefile->GetDefinition("CMAKE_FIND_PACKAGE_SORT_DIRECTION")) {
this->SortDirection = (*sd == "ASC") ? Asc : Dec;
}
@@ -265,9 +644,9 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
cmsys::RegularExpression versionRegex(
R"V(^([0-9]+(\.[0-9]+)*)(\.\.\.(<?)([0-9]+(\.[0-9]+)*))?$)V");
bool haveVersion = false;
- std::set<unsigned int> configArgs;
- std::set<unsigned int> moduleArgs;
- for (unsigned int i = 1; i < args.size(); ++i) {
+ std::vector<std::size_t> configArgs;
+ std::vector<std::size_t> moduleArgs;
+ for (std::size_t i = 1u; i < args.size(); ++i) {
if (args[i] == "QUIET") {
this->Quiet = true;
doing = DoingNone;
@@ -281,17 +660,17 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
this->GlobalScope = true;
doing = DoingNone;
} else if (args[i] == "MODULE") {
- moduleArgs.insert(i);
+ moduleArgs.push_back(i);
doing = DoingNone;
// XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
// NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "CONFIG") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
// XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
// NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "NO_MODULE") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
} else if (args[i] == "REQUIRED") {
this->Required = true;
@@ -301,36 +680,36 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
} else if (args[i] == "OPTIONAL_COMPONENTS") {
doing = DoingOptionalComponents;
} else if (args[i] == "NAMES") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNames;
} else if (args[i] == "PATHS") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingPaths;
} else if (args[i] == "HINTS") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingHints;
} else if (args[i] == "PATH_SUFFIXES") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingPathSuffixes;
} else if (args[i] == "CONFIGS") {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingConfigs;
} else if (args[i] == "NO_POLICY_SCOPE") {
this->PolicyScope = false;
doing = DoingNone;
} else if (args[i] == "NO_CMAKE_PACKAGE_REGISTRY") {
this->NoUserRegistry = true;
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
} else if (args[i] == "NO_CMAKE_SYSTEM_PACKAGE_REGISTRY") {
this->NoSystemRegistry = true;
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
// XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
// NOLINTNEXTLINE(bugprone-branch-clone)
} else if (args[i] == "NO_CMAKE_BUILDS_PATH") {
// Ignore legacy option.
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
} else if (args[i] == "REGISTRY_VIEW") {
if (++i == args.size()) {
@@ -347,7 +726,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
return false;
}
} else if (this->CheckCommonArgument(args[i])) {
- configArgs.insert(i);
+ configArgs.push_back(i);
doing = DoingNone;
} else if ((doing == DoingComponents) ||
(doing == DoingOptionalComponents)) {
@@ -361,8 +740,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
requiredComponents.insert(args[i]);
}
- std::string req_var = this->Name + "_FIND_REQUIRED_" + args[i];
- componentVarDefs.emplace_back(req_var, isRequired);
+ componentVarDefs.emplace_back(this->Name + "_FIND_REQUIRED_" + args[i],
+ isRequired);
// Append to the list of required components.
components += components_sep;
@@ -420,11 +799,11 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
if (!this->UseFindModules && !this->UseConfigFiles) {
std::ostringstream e;
e << "given options exclusive to Module mode:\n";
- for (unsigned int si : moduleArgs) {
+ for (auto si : moduleArgs) {
e << " " << args[si] << "\n";
}
e << "and options exclusive to Config mode:\n";
- for (unsigned int si : configArgs) {
+ for (auto si : configArgs) {
e << " " << args[si] << "\n";
}
e << "The options are incompatible.";
@@ -443,20 +822,20 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
if (this->VersionComplete.empty() || components.empty()) {
// Check whether we are recursing inside "Find<name>.cmake" within
// another find_package(<name>) call.
- std::string mod = cmStrCat(this->Name, "_FIND_MODULE");
+ std::string const mod = cmStrCat(this->Name, "_FIND_MODULE");
if (this->Makefile->IsOn(mod)) {
if (this->VersionComplete.empty()) {
// Get version information from the outer call if necessary.
// Requested version string.
- std::string ver = cmStrCat(this->Name, "_FIND_VERSION_COMPLETE");
+ std::string const ver = cmStrCat(this->Name, "_FIND_VERSION_COMPLETE");
this->VersionComplete = this->Makefile->GetSafeDefinition(ver);
// Whether an exact version is required.
- std::string exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT");
+ std::string const exact = cmStrCat(this->Name, "_FIND_VERSION_EXACT");
this->VersionExact = this->Makefile->IsOn(exact);
}
if (components.empty()) {
- std::string components_var = this->Name + "_FIND_COMPONENTS";
+ std::string const components_var = this->Name + "_FIND_COMPONENTS";
components = this->Makefile->GetSafeDefinition(components_var);
}
}
@@ -497,15 +876,6 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
return false;
}
- // Parse the version number and store the results that were
- // successfully parsed.
- auto parseVersion = [](const std::string& version, unsigned int& major,
- unsigned int& minor, unsigned int& patch,
- unsigned int& tweak) -> unsigned int {
- return sscanf(version.c_str(), "%u.%u.%u.%u", &major, &minor, &patch,
- &tweak);
- };
-
if (!this->Version.empty()) {
this->VersionCount =
parseVersion(this->Version, this->VersionMajor, this->VersionMinor,
@@ -533,7 +903,7 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
}
}
- std::string disableFindPackageVar =
+ std::string const disableFindPackageVar =
cmStrCat("CMAKE_DISABLE_FIND_PACKAGE_", this->Name);
if (this->Makefile->IsOn(disableFindPackageVar)) {
if (this->Required) {
@@ -557,8 +927,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
// A dependency provider (if set) gets first look before other methods.
// We do this before modifying the package root path stack because a
// provider might use methods that ignore that.
- cmState* state = this->Makefile->GetState();
- cmState::Command providerCommand = state->GetDependencyProviderCommand(
+ cmState* const state = this->Makefile->GetState();
+ cmState::Command const providerCommand = state->GetDependencyProviderCommand(
cmDependencyProvider::Method::FindPackage);
if (bypassProvider) {
if (this->DebugMode && providerCommand) {
@@ -725,11 +1095,8 @@ bool cmFindPackageCommand::InitialPass(std::vector<std::string> const& args)
"package configuration file provided by "
<< this->Name << " (" << this->Name << "Config.cmake or "
<< cmSystemTools::LowerCase(this->Name)
- << "-config.cmake). "
- "Otherwise make Find"
- << this->Name
- << ".cmake available in "
- "CMAKE_MODULE_PATH.";
+ << "-config.cmake). Otherwise make Find" << this->Name
+ << ".cmake available in CMAKE_MODULE_PATH.";
}
aw << "\n"
"(Variable CMAKE_FIND_PACKAGE_WARN_NO_MODULE enabled this "
@@ -813,22 +1180,22 @@ bool cmFindPackageCommand::FindPackageUsingConfigMode()
void cmFindPackageCommand::SetVersionVariables(
const std::function<void(const std::string&, cm::string_view)>&
addDefinition,
- const std::string& prefix, const std::string& version, unsigned int count,
- unsigned int major, unsigned int minor, unsigned int patch,
- unsigned int tweak)
+ const std::string& prefix, const std::string& version,
+ const unsigned int count, const unsigned int major, const unsigned int minor,
+ const unsigned int patch, const unsigned int tweak)
{
addDefinition(prefix, version);
char buf[64];
snprintf(buf, sizeof(buf), "%u", major);
addDefinition(prefix + "_MAJOR", buf);
- sprintf(buf, "%u", minor);
+ snprintf(buf, sizeof(buf), "%u", minor);
addDefinition(prefix + "_MINOR", buf);
- sprintf(buf, "%u", patch);
+ snprintf(buf, sizeof(buf), "%u", patch);
addDefinition(prefix + "_PATCH", buf);
- sprintf(buf, "%u", tweak);
+ snprintf(buf, sizeof(buf), "%u", tweak);
addDefinition(prefix + "_TWEAK", buf);
- sprintf(buf, "%u", count);
+ snprintf(buf, sizeof(buf), "%u", count);
addDefinition(prefix + "_COUNT", buf);
}
@@ -910,7 +1277,7 @@ void cmFindPackageCommand::SetModuleVariables(
}
void cmFindPackageCommand::AddFindDefinition(const std::string& var,
- cm::string_view value)
+ const cm::string_view value)
{
if (cmValue old = this->Makefile->GetDefinition(var)) {
this->OriginalDefs[var].exists = true;
@@ -954,7 +1321,7 @@ bool cmFindPackageCommand::FindModule(bool& found)
if (!mfile.empty()) {
if (system) {
- auto it = this->DeprecatedFindModules.find(this->Name);
+ auto const it = this->DeprecatedFindModules.find(this->Name);
if (it != this->DeprecatedFindModules.end()) {
cmPolicies::PolicyStatus status =
this->Makefile->GetPolicyStatus(it->second);
@@ -978,13 +1345,13 @@ bool cmFindPackageCommand::FindModule(bool& found)
// Load the module we found, and set "<name>_FIND_MODULE" to true
// while inside it.
found = true;
- std::string var = cmStrCat(this->Name, "_FIND_MODULE");
+ std::string const var = cmStrCat(this->Name, "_FIND_MODULE");
this->Makefile->AddDefinition(var, "1");
bool result = this->ReadListFile(mfile, DoPolicyScope);
this->Makefile->RemoveDefinition(var);
if (this->DebugMode) {
- std::string foundVar = cmStrCat(this->Name, "_FOUND");
+ std::string const foundVar = cmStrCat(this->Name, "_FOUND");
if (this->Makefile->IsDefinitionSet(foundVar) &&
!this->Makefile->IsOn(foundVar)) {
@@ -999,7 +1366,7 @@ bool cmFindPackageCommand::FindModule(bool& found)
}
bool cmFindPackageCommand::HandlePackageMode(
- HandlePackageModeType handlePackageModeType)
+ const HandlePackageModeType handlePackageModeType)
{
this->ConsideredConfigs.clear();
@@ -1042,8 +1409,9 @@ bool cmFindPackageCommand::HandlePackageMode(
}
}
- std::string foundVar = cmStrCat(this->Name, "_FOUND");
- std::string notFoundMessageVar = cmStrCat(this->Name, "_NOT_FOUND_MESSAGE");
+ std::string const foundVar = cmStrCat(this->Name, "_FOUND");
+ std::string const notFoundMessageVar =
+ cmStrCat(this->Name, "_NOT_FOUND_MESSAGE");
std::string notFoundMessage;
// If the directory for the config file was found, try to read the file.
@@ -1123,8 +1491,9 @@ bool cmFindPackageCommand::HandlePackageMode(
<< (this->VersionExact ? "exactly matches" : "is compatible with")
<< " requested version "
<< (this->VersionRange.empty() ? "" : "range ") << "\""
- << this->VersionComplete << "\".\n"
- << "The following configuration files were considered but not "
+ << this->VersionComplete
+ << "\".\n"
+ "The following configuration files were considered but not "
"accepted:\n";
for (ConfigFileInfo const& info :
@@ -1172,8 +1541,9 @@ bool cmFindPackageCommand::HandlePackageMode(
"package or SDK, be sure it has been installed.";
} else // if(!this->UseFindModules && !this->UseConfigFiles)
{
- e << "No \"Find" << this->Name << ".cmake\" found in "
- << "CMAKE_MODULE_PATH.";
+ e << "No \"Find" << this->Name
+ << ".cmake\" found in "
+ "CMAKE_MODULE_PATH.";
aw
<< "Find" << this->Name
@@ -1217,16 +1587,16 @@ bool cmFindPackageCommand::HandlePackageMode(
this->Makefile->AddDefinition(foundVar, found ? "1" : "0");
// Set a variable naming the configuration file that was found.
- std::string fileVar = cmStrCat(this->Name, "_CONFIG");
+ std::string const fileVar = cmStrCat(this->Name, "_CONFIG");
if (found) {
this->Makefile->AddDefinition(fileVar, this->FileFound);
} else {
this->Makefile->RemoveDefinition(fileVar);
}
- std::string consideredConfigsVar =
+ std::string const consideredConfigsVar =
cmStrCat(this->Name, "_CONSIDERED_CONFIGS");
- std::string consideredVersionsVar =
+ std::string const consideredVersionsVar =
cmStrCat(this->Name, "_CONSIDERED_VERSIONS");
std::string consideredConfigFiles;
@@ -1312,7 +1682,7 @@ bool cmFindPackageCommand::FindConfig()
void cmFindPackageCommand::SetConfigDirCacheVariable(const std::string& value)
{
- std::string help =
+ std::string const help =
cmStrCat("The directory containing a CMake configuration file for ",
this->Name, '.');
this->Makefile->AddCacheDefinition(this->Variable, value, help.c_str(),
@@ -1351,7 +1721,7 @@ bool cmFindPackageCommand::FindAppBundleConfig()
}
bool cmFindPackageCommand::ReadListFile(const std::string& f,
- PolicyScopeRule psr)
+ const PolicyScopeRule psr)
{
const bool noPolicyScope = !this->PolicyScope || psr == NoPolicyScope;
@@ -1362,12 +1732,12 @@ bool cmFindPackageCommand::ReadListFile(const std::string& f,
if (this->Makefile->ReadDependentFile(f, noPolicyScope)) {
return true;
}
- std::string e = cmStrCat("Error reading CMake code from \"", f, "\".");
+ std::string const e = cmStrCat("Error reading CMake code from \"", f, "\".");
this->SetError(e);
return false;
}
-void cmFindPackageCommand::AppendToFoundProperty(bool found)
+void cmFindPackageCommand::AppendToFoundProperty(const bool found)
{
std::vector<std::string> foundContents;
cmValue foundProp =
@@ -1410,27 +1780,28 @@ void cmFindPackageCommand::AppendToFoundProperty(bool found)
void cmFindPackageCommand::AppendSuccessInformation()
{
{
- std::string transitivePropName =
+ std::string const transitivePropName =
cmStrCat("_CMAKE_", this->Name, "_TRANSITIVE_DEPENDENCY");
this->Makefile->GetState()->SetGlobalProperty(transitivePropName, "False");
}
- std::string found = cmStrCat(this->Name, "_FOUND");
- std::string upperFound = cmSystemTools::UpperCase(found);
+ std::string const found = cmStrCat(this->Name, "_FOUND");
+ std::string const upperFound = cmSystemTools::UpperCase(found);
- bool upperResult = this->Makefile->IsOn(upperFound);
- bool result = this->Makefile->IsOn(found);
- bool packageFound = (result || upperResult);
+ bool const upperResult = this->Makefile->IsOn(upperFound);
+ bool const result = this->Makefile->IsOn(found);
+ bool const packageFound = (result || upperResult);
this->AppendToFoundProperty(packageFound);
// Record whether the find was quiet or not, so this can be used
// e.g. in FeatureSummary.cmake
- std::string quietInfoPropName = cmStrCat("_CMAKE_", this->Name, "_QUIET");
+ std::string const quietInfoPropName =
+ cmStrCat("_CMAKE_", this->Name, "_QUIET");
this->Makefile->GetState()->SetGlobalProperty(
quietInfoPropName, this->Quiet ? "TRUE" : "FALSE");
// set a global property to record the required version of this package
- std::string versionInfoPropName =
+ std::string const versionInfoPropName =
cmStrCat("_CMAKE_", this->Name, "_REQUIRED_VERSION");
std::string versionInfo;
if (!this->VersionRange.empty()) {
@@ -1442,28 +1813,13 @@ void cmFindPackageCommand::AppendSuccessInformation()
this->Makefile->GetState()->SetGlobalProperty(versionInfoPropName,
versionInfo.c_str());
if (this->Required) {
- std::string requiredInfoPropName =
+ std::string const requiredInfoPropName =
cmStrCat("_CMAKE_", this->Name, "_TYPE");
this->Makefile->GetState()->SetGlobalProperty(requiredInfoPropName,
"REQUIRED");
}
}
-inline std::size_t collectPathsForDebug(std::string& buffer,
- cmSearchPath const& searchPath,
- std::size_t startIndex = 0)
-{
- const auto& paths = searchPath.GetPaths();
- if (paths.empty()) {
- buffer += " none\n";
- return 0;
- }
- for (std::size_t i = startIndex; i < paths.size(); i++) {
- buffer += " " + paths[i].Path + "\n";
- }
- return paths.size();
-}
-
void cmFindPackageCommand::ComputePrefixes()
{
this->FillPrefixesPackageRedirect();
@@ -1674,14 +2030,6 @@ void cmFindPackageCommand::FillPrefixesSystemRegistry()
}
#if defined(_WIN32) && !defined(__CYGWIN__)
-# include <windows.h>
-// http://msdn.microsoft.com/en-us/library/aa384253%28v=vs.85%29.aspx
-# if !defined(KEY_WOW64_32KEY)
-# define KEY_WOW64_32KEY 0x0200
-# endif
-# if !defined(KEY_WOW64_64KEY)
-# define KEY_WOW64_64KEY 0x0100
-# endif
void cmFindPackageCommand::LoadPackageRegistryWinUser()
{
// HKEY_CURRENT_USER\\Software shares 32-bit and 64-bit views.
@@ -1704,7 +2052,8 @@ void cmFindPackageCommand::LoadPackageRegistryWinSystem()
}
}
-void cmFindPackageCommand::LoadPackageRegistryWin(bool user, unsigned int view,
+void cmFindPackageCommand::LoadPackageRegistryWin(const bool user,
+ const unsigned int view,
cmSearchPath& outPaths)
{
std::wstring key = L"Software\\Kitware\\CMake\\Packages\\";
@@ -1756,28 +2105,8 @@ void cmFindPackageCommand::LoadPackageRegistryWin(bool user, unsigned int view,
RegCloseKey(hKey);
}
}
-#else
-class cmFindPackageCommandHoldFile
-{
- const char* File;
-
-public:
- cmFindPackageCommandHoldFile(const char* f)
- : File(f)
- {
- }
- ~cmFindPackageCommandHoldFile()
- {
- if (this->File) {
- cmSystemTools::RemoveFile(this->File);
- }
- }
- cmFindPackageCommandHoldFile(const cmFindPackageCommandHoldFile&) = delete;
- cmFindPackageCommandHoldFile& operator=(
- const cmFindPackageCommandHoldFile&) = delete;
- void Release() { this->File = nullptr; }
-};
+#else
void cmFindPackageCommand::LoadPackageRegistryDir(std::string const& dir,
cmSearchPath& outPaths)
{
@@ -1877,7 +2206,7 @@ void cmFindPackageCommand::FillPrefixesCMakeSystemVariable()
std::vector<std::string> expanded = cmExpandedList(*prefix_paths);
long count = 0;
for (const auto& path : expanded) {
- bool to_add =
+ bool const to_add =
!(path == install_path_to_remove && ++count == install_prefix_count);
if (to_add) {
paths.AddPath(path);
@@ -1941,7 +2270,7 @@ bool cmFindPackageCommand::SearchDirectory(std::string const& dir)
std::string d = dir;
if (!s.empty()) {
d += s;
- d += "/";
+ d += '/';
}
if (this->CheckDirectory(d)) {
return true;
@@ -1955,7 +2284,7 @@ bool cmFindPackageCommand::CheckDirectory(std::string const& dir)
assert(!dir.empty() && dir.back() == '/');
// Look for the file in this directory.
- std::string d = dir.substr(0, dir.size() - 1);
+ std::string const d = dir.substr(0, dir.size() - 1);
if (this->FindConfigFile(d, this->FileFound)) {
// Remove duplicate slashes.
cmSystemTools::ConvertToUnixSlashes(this->FileFound);
@@ -2028,8 +2357,8 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
std::string& result_version)
{
// The version file will be loaded in an isolated scope.
- cmMakefile::ScopePushPop varScope(this->Makefile);
- cmMakefile::PolicyPushPop polScope(this->Makefile);
+ cmMakefile::ScopePushPop const varScope(this->Makefile);
+ cmMakefile::PolicyPushPop const polScope(this->Makefile);
static_cast<void>(varScope);
static_cast<void>(polScope);
@@ -2076,7 +2405,7 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
if (this->ReadListFile(version_file, NoPolicyScope)) {
// Check the output variables.
bool okay = this->Makefile->IsOn("PACKAGE_VERSION_EXACT");
- bool unsuitable = this->Makefile->IsOn("PACKAGE_VERSION_UNSUITABLE");
+ bool const unsuitable = this->Makefile->IsOn("PACKAGE_VERSION_UNSUITABLE");
if (!okay && !this->VersionExact) {
okay = this->Makefile->IsOn("PACKAGE_VERSION_COMPATIBLE");
}
@@ -2096,8 +2425,8 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
unsigned int parsed_patch;
unsigned int parsed_tweak;
this->VersionFoundCount =
- sscanf(this->VersionFound.c_str(), "%u.%u.%u.%u", &parsed_major,
- &parsed_minor, &parsed_patch, &parsed_tweak);
+ parseVersion(this->VersionFound, parsed_major, parsed_minor,
+ parsed_patch, parsed_tweak);
switch (this->VersionFoundCount) {
case 4:
this->VersionFoundTweak = parsed_tweak;
@@ -2129,7 +2458,7 @@ bool cmFindPackageCommand::CheckVersionFile(std::string const& version_file,
void cmFindPackageCommand::StoreVersionFound()
{
// Store the whole version string.
- std::string ver = cmStrCat(this->Name, "_VERSION");
+ std::string const ver = cmStrCat(this->Name, "_VERSION");
auto addDefinition = [this](const std::string& variable,
cm::string_view value) {
this->Makefile->AddDefinition(variable, value);
@@ -2145,357 +2474,6 @@ void cmFindPackageCommand::StoreVersionFound()
}
}
-class cmFileListGeneratorBase
-{
-public:
- virtual ~cmFileListGeneratorBase() = default;
-
-protected:
- bool Consider(std::string const& fullPath, cmFileList& listing);
-
-private:
- bool Search(cmFileList&);
- virtual bool Search(std::string const& parent, cmFileList&) = 0;
- virtual std::unique_ptr<cmFileListGeneratorBase> Clone() const = 0;
- friend class cmFileList;
- cmFileListGeneratorBase* SetNext(cmFileListGeneratorBase const& next);
- std::unique_ptr<cmFileListGeneratorBase> Next;
-};
-
-class cmFileList
-{
-public:
- virtual ~cmFileList() = default;
- cmFileList& operator/(cmFileListGeneratorBase const& rhs)
- {
- if (this->Last) {
- this->Last = this->Last->SetNext(rhs);
- } else {
- this->First = rhs.Clone();
- this->Last = this->First.get();
- }
- return *this;
- }
- bool Search()
- {
- if (this->First) {
- return this->First->Search(*this);
- }
- return false;
- }
-
-private:
- virtual bool Visit(std::string const& fullPath) = 0;
- friend class cmFileListGeneratorBase;
- std::unique_ptr<cmFileListGeneratorBase> First;
- cmFileListGeneratorBase* Last = nullptr;
-};
-
-class cmFindPackageFileList : public cmFileList
-{
-public:
- cmFindPackageFileList(cmFindPackageCommand* fpc, bool use_suffixes = true)
- : FPC(fpc)
- , UseSuffixes(use_suffixes)
- {
- }
-
-private:
- bool Visit(std::string const& fullPath) override
- {
- if (this->UseSuffixes) {
- return this->FPC->SearchDirectory(fullPath);
- }
- return this->FPC->CheckDirectory(fullPath);
- }
- cmFindPackageCommand* FPC;
- bool UseSuffixes;
-};
-
-bool cmFileListGeneratorBase::Search(cmFileList& listing)
-{
- return this->Search("", listing);
-}
-
-cmFileListGeneratorBase* cmFileListGeneratorBase::SetNext(
- cmFileListGeneratorBase const& next)
-{
- this->Next = next.Clone();
- return this->Next.get();
-}
-
-bool cmFileListGeneratorBase::Consider(std::string const& fullPath,
- cmFileList& listing)
-{
- if (!fullPath.empty() && !cmSystemTools::FileIsDirectory(fullPath)) {
- return false;
- }
- if (this->Next) {
- return this->Next->Search(fullPath + "/", listing);
- }
- return listing.Visit(fullPath + "/");
-}
-
-class cmFileListGeneratorFixed : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorFixed(std::string str)
- : String(std::move(str))
- {
- }
- cmFileListGeneratorFixed(cmFileListGeneratorFixed const& r)
- : String(r.String)
- {
- }
-
-private:
- std::string String;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- std::string fullPath = parent + this->String;
- return this->Consider(fullPath, lister);
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorFixed(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorEnumerate : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorEnumerate(std::vector<std::string> const& v)
- : Vector(v)
- {
- }
- cmFileListGeneratorEnumerate(cmFileListGeneratorEnumerate const& r)
- : Vector(r.Vector)
- {
- }
-
-private:
- std::vector<std::string> const& Vector;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- for (std::string const& i : this->Vector) {
- if (this->Consider(parent + i, lister)) {
- return true;
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorEnumerate(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorProject : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorProject(std::vector<std::string> const& names,
- cmFindPackageCommand::SortOrderType so,
- cmFindPackageCommand::SortDirectionType sd)
- : Names(names)
- {
- this->SetSort(so, sd);
- }
- cmFileListGeneratorProject(cmFileListGeneratorProject const& r)
- : Names(r.Names)
- {
- this->SetSort(r.SortOrder, r.SortDirection);
- }
-
- void SetSort(cmFindPackageCommand::SortOrderType o,
- cmFindPackageCommand::SortDirectionType d)
- {
- this->SortOrder = o;
- this->SortDirection = d;
- }
-
-protected:
- // sort parameters
- cmFindPackageCommand::SortOrderType SortOrder;
- cmFindPackageCommand::SortDirectionType SortDirection;
-
-private:
- std::vector<std::string> const& Names;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- // Construct a list of matches.
- std::vector<std::string> matches;
- cmsys::Directory d;
- d.Load(parent);
- for (unsigned long i = 0; i < d.GetNumberOfFiles(); ++i) {
- const char* fname = d.GetFile(i);
- if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) {
- continue;
- }
- for (std::string const& n : this->Names) {
- if (cmsysString_strncasecmp(fname, n.c_str(), n.length()) == 0) {
- matches.emplace_back(fname);
- }
- }
- }
-
- // before testing the matches check if there is a specific sorting order to
- // perform
- if (this->SortOrder != cmFindPackageCommand::None) {
- cmFindPackageCommand::Sort(matches.begin(), matches.end(),
- this->SortOrder, this->SortDirection);
- }
-
- for (std::string const& i : matches) {
- if (this->Consider(parent + i, lister)) {
- return true;
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorProject(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorMacProject : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorMacProject(std::vector<std::string> const& names,
- const char* ext)
- : Names(names)
- , Extension(ext)
- {
- }
- cmFileListGeneratorMacProject(cmFileListGeneratorMacProject const& r)
- : Names(r.Names)
- , Extension(r.Extension)
- {
- }
-
-private:
- std::vector<std::string> const& Names;
- std::string Extension;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- // Construct a list of matches.
- std::vector<std::string> matches;
- cmsys::Directory d;
- d.Load(parent);
- for (unsigned long i = 0; i < d.GetNumberOfFiles(); ++i) {
- const char* fname = d.GetFile(i);
- if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) {
- continue;
- }
- for (std::string name : this->Names) {
- name += this->Extension;
- if (cmsysString_strcasecmp(fname, name.c_str()) == 0) {
- matches.emplace_back(fname);
- }
- }
- }
-
- for (std::string const& i : matches) {
- if (this->Consider(parent + i, lister)) {
- return true;
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorMacProject(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorCaseInsensitive : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorCaseInsensitive(std::string str)
- : String(std::move(str))
- {
- }
- cmFileListGeneratorCaseInsensitive(
- cmFileListGeneratorCaseInsensitive const& r)
- : String(r.String)
- {
- }
-
-private:
- std::string String;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- // Look for matching files.
- std::vector<std::string> matches;
- cmsys::Directory d;
- d.Load(parent);
- for (unsigned long i = 0; i < d.GetNumberOfFiles(); ++i) {
- const char* fname = d.GetFile(i);
- if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) {
- continue;
- }
- if (cmsysString_strcasecmp(fname, this->String.c_str()) == 0) {
- if (this->Consider(parent + fname, lister)) {
- return true;
- }
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- std::unique_ptr<cmFileListGeneratorBase> g(
- new cmFileListGeneratorCaseInsensitive(*this));
- return g;
- }
-};
-
-class cmFileListGeneratorGlob : public cmFileListGeneratorBase
-{
-public:
- cmFileListGeneratorGlob(std::string str)
- : Pattern(std::move(str))
- {
- }
- cmFileListGeneratorGlob(cmFileListGeneratorGlob const& r)
- : Pattern(r.Pattern)
- {
- }
-
-private:
- std::string Pattern;
- bool Search(std::string const& parent, cmFileList& lister) override
- {
- // Glob the set of matching files.
- std::string expr = cmStrCat(parent, this->Pattern);
- cmsys::Glob g;
- if (!g.FindFiles(expr)) {
- return false;
- }
- std::vector<std::string> const& files = g.GetFiles();
-
- // Look for directories among the matches.
- for (std::string const& f : files) {
- if (this->Consider(f, lister)) {
- return true;
- }
- }
- return false;
- }
- std::unique_ptr<cmFileListGeneratorBase> Clone() const override
- {
- return cm::make_unique<cmFileListGeneratorGlob>(*this);
- }
-};
-
bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
{
assert(!prefix_in.empty() && prefix_in.back() == '/');
@@ -2515,148 +2493,101 @@ bool cmFindPackageCommand::SearchPrefix(std::string const& prefix_in)
return false;
}
- // PREFIX/ (useful on windows or in build trees)
+ // PREFIX/ (useful on windows or in build trees)
if (this->SearchDirectory(prefix_in)) {
return true;
}
// Strip the trailing slash because the path generator is about to
// add one.
- std::string prefix = prefix_in.substr(0, prefix_in.size() - 1);
+ std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
- // PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
+ auto searchFn = [this](const std::string& fullPath) -> bool {
+ return this->SearchDirectory(fullPath);
+ };
+
+ auto iCMakeGen = cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s };
+ auto firstPkgDirGen =
+ cmProjectDirectoryListGenerator{ this->Names, this->SortOrder,
+ this->SortDirection };
+
+ // PREFIX/(cmake|CMake)/ (useful on windows or in build trees)
+ if (TryGeneratedPaths(searchFn, prefix, iCMakeGen)) {
+ return true;
}
- // PREFIX/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ // PREFIX/(Foo|foo|FOO).*/
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen)) {
+ return true;
}
- // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
+ // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, iCMakeGen)) {
+ return true;
+ }
+
+ auto secondPkgDirGen =
+ cmProjectDirectoryListGenerator{ this->Names, this->SortOrder,
+ this->SortDirection };
+
+ // PREFIX/(Foo|foo|FOO).*/(cmake|CMake)/(Foo|foo|FOO).*/
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, iCMakeGen,
+ secondPkgDirGen)) {
+ return true;
}
// Construct list of common install locations (lib and share).
- std::vector<std::string> common;
+ std::vector<cm::string_view> common;
+ std::string libArch;
if (!this->LibraryArchitecture.empty()) {
- common.push_back("lib/" + this->LibraryArchitecture);
+ libArch = "lib/" + this->LibraryArchitecture;
+ common.emplace_back(libArch);
}
if (this->UseLib32Paths) {
- common.emplace_back("lib32");
+ common.emplace_back("lib32"_s);
}
if (this->UseLib64Paths) {
- common.emplace_back("lib64");
+ common.emplace_back("lib64"_s);
}
if (this->UseLibx32Paths) {
- common.emplace_back("libx32");
+ common.emplace_back("libx32"_s);
}
- common.emplace_back("lib");
- common.emplace_back("share");
+ common.emplace_back("lib"_s);
+ common.emplace_back("share"_s);
- // PREFIX/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorFixed("cmake") /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ auto cmnGen = cmEnumPathSegmentsGenerator{ common };
+ auto cmakeGen = cmAppendPathSegmentGenerator{ "cmake"_s };
+
+ // PREFIX/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
+ if (TryGeneratedPaths(searchFn, prefix, cmnGen, cmakeGen, firstPkgDirGen)) {
+ return true;
}
- // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/
+ if (TryGeneratedPaths(searchFn, prefix, cmnGen, firstPkgDirGen)) {
+ return true;
}
- // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/(cmake|CMake)/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
+ // PREFIX/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/(cmake|CMake)/
+ if (TryGeneratedPaths(searchFn, prefix, cmnGen, firstPkgDirGen, iCMakeGen)) {
+ return true;
}
// PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/cmake/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorFixed("cmake") /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen, cmakeGen,
+ secondPkgDirGen)) {
+ return true;
}
// PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection);
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen,
+ secondPkgDirGen)) {
+ return true;
}
// PREFIX/(Foo|foo|FOO).*/(lib/ARCH|lib*|share)/(Foo|foo|FOO).*/(cmake|CMake)/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorEnumerate(common) /
- cmFileListGeneratorProject(this->Names, this->SortOrder,
- this->SortDirection) /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
- }
-
- return false;
+ return TryGeneratedPaths(searchFn, prefix, firstPkgDirGen, cmnGen,
+ secondPkgDirGen, iCMakeGen);
}
bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
@@ -2665,56 +2596,36 @@ bool cmFindPackageCommand::SearchFrameworkPrefix(std::string const& prefix_in)
// Strip the trailing slash because the path generator is about to
// add one.
- std::string prefix = prefix_in.substr(0, prefix_in.size() - 1);
+ std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
+
+ auto searchFn = [this](const std::string& fullPath) -> bool {
+ return this->SearchDirectory(fullPath);
+ };
+
+ auto iCMakeGen = cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s };
+ auto fwGen =
+ cmMacProjectDirectoryListGenerator{ this->Names, ".framework"_s };
+ auto rGen = cmAppendPathSegmentGenerator{ "Resources"_s };
+ auto vGen = cmAppendPathSegmentGenerator{ "Versions"_s };
+ auto grGen = cmFileListGeneratorGlob{ "/*/Resources"_s };
// <prefix>/Foo.framework/Resources/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".framework") /
- cmFileListGeneratorFixed("Resources");
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, fwGen, rGen)) {
+ return true;
}
+
// <prefix>/Foo.framework/Resources/CMake/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".framework") /
- cmFileListGeneratorFixed("Resources") /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, fwGen, rGen, iCMakeGen)) {
+ return true;
}
// <prefix>/Foo.framework/Versions/*/Resources/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".framework") /
- cmFileListGeneratorFixed("Versions") /
- cmFileListGeneratorGlob("*/Resources");
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, fwGen, vGen, grGen)) {
+ return true;
}
// <prefix>/Foo.framework/Versions/*/Resources/CMake/
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".framework") /
- cmFileListGeneratorFixed("Versions") /
- cmFileListGeneratorGlob("*/Resources") /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
- }
-
- return false;
+ return TryGeneratedPaths(searchFn, prefix, fwGen, vGen, grGen, iCMakeGen);
}
bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
@@ -2723,32 +2634,24 @@ bool cmFindPackageCommand::SearchAppBundlePrefix(std::string const& prefix_in)
// Strip the trailing slash because the path generator is about to
// add one.
- std::string prefix = prefix_in.substr(0, prefix_in.size() - 1);
+ std::string const prefix = prefix_in.substr(0, prefix_in.size() - 1);
+
+ auto searchFn = [this](const std::string& fullPath) -> bool {
+ return this->SearchDirectory(fullPath);
+ };
+
+ auto appGen = cmMacProjectDirectoryListGenerator{ this->Names, ".app"_s };
+ auto crGen = cmAppendPathSegmentGenerator{ "Contents/Resources"_s };
// <prefix>/Foo.app/Contents/Resources
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".app") /
- cmFileListGeneratorFixed("Contents/Resources");
- if (lister.Search()) {
- return true;
- }
+ if (TryGeneratedPaths(searchFn, prefix, appGen, crGen)) {
+ return true;
}
// <prefix>/Foo.app/Contents/Resources/CMake
- {
- cmFindPackageFileList lister(this);
- lister / cmFileListGeneratorFixed(prefix) /
- cmFileListGeneratorMacProject(this->Names, ".app") /
- cmFileListGeneratorFixed("Contents/Resources") /
- cmFileListGeneratorCaseInsensitive("cmake");
- if (lister.Search()) {
- return true;
- }
- }
-
- return false;
+ return TryGeneratedPaths(
+ searchFn, prefix, appGen, crGen,
+ cmCaseInsensitiveDirectoryListGenerator{ "cmake"_s });
}
// TODO: Debug cmsys::Glob double slash problem.
diff --git a/Source/cmFindPackageCommand.h b/Source/cmFindPackageCommand.h
index 80fd8f8..28e00a1 100644
--- a/Source/cmFindPackageCommand.h
+++ b/Source/cmFindPackageCommand.h
@@ -153,8 +153,6 @@ private:
bool SearchFrameworkPrefix(std::string const& prefix_in);
bool SearchAppBundlePrefix(std::string const& prefix_in);
- friend class cmFindPackageFileList;
-
struct OriginalDef
{
bool exists;
diff --git a/Source/cmFindPathCommand.cxx b/Source/cmFindPathCommand.cxx
index 27074ff..74a69d8 100644
--- a/Source/cmFindPathCommand.cxx
+++ b/Source/cmFindPathCommand.cxx
@@ -88,7 +88,8 @@ std::string cmFindPathCommand::FindHeaderInFramework(
if (!frameWorkName.empty()) {
std::string fpath = cmStrCat(dir, frameWorkName, ".framework");
std::string intPath = cmStrCat(fpath, "/Headers/", fileName);
- if (cmSystemTools::FileExists(intPath)) {
+ if (cmSystemTools::FileExists(intPath) &&
+ this->Validate(this->IncludeFileInPath ? intPath : fpath)) {
debug.FoundAt(intPath);
if (this->IncludeFileInPath) {
return intPath;
@@ -124,7 +125,8 @@ std::string cmFindPathCommand::FindNormalHeader(cmFindBaseDebugState& debug)
for (std::string const& n : this->Names) {
for (std::string const& sp : this->SearchPaths) {
tryPath = cmStrCat(sp, n);
- if (cmSystemTools::FileExists(tryPath)) {
+ if (cmSystemTools::FileExists(tryPath) &&
+ this->Validate(this->IncludeFileInPath ? tryPath : sp)) {
debug.FoundAt(tryPath);
if (this->IncludeFileInPath) {
return tryPath;
diff --git a/Source/cmFindProgramCommand.cxx b/Source/cmFindProgramCommand.cxx
index a64e0e4..8a2a69e 100644
--- a/Source/cmFindProgramCommand.cxx
+++ b/Source/cmFindProgramCommand.cxx
@@ -27,6 +27,7 @@ struct cmFindProgramHelper
cmFindBase const* base)
: DebugSearches(std::move(debugName), base)
, Makefile(makefile)
+ , FindBase(base)
, PolicyCMP0109(makefile->GetPolicyStatus(cmPolicies::CMP0109))
{
#if defined(_WIN32) || defined(__CYGWIN__) || defined(__MINGW32__)
@@ -56,6 +57,7 @@ struct cmFindProgramHelper
// Debug state
cmFindBaseDebugState DebugSearches;
cmMakefile* Makefile;
+ cmFindBase const* FindBase;
cmPolicies::PolicyStatus PolicyCMP0109;
@@ -94,7 +96,7 @@ struct cmFindProgramHelper
this->TestNameExt = cmStrCat(name, ext);
this->TestPath = cmSystemTools::CollapseFullPath(
this->TestNameExt, path);
- bool exists = this->FileIsExecutable(this->TestPath);
+ bool exists = this->FileIsValid(this->TestPath);
exists ? this->DebugSearches.FoundAt(this->TestPath)
: this->DebugSearches.FailedAt(this->TestPath);
if (exists) {
@@ -104,12 +106,12 @@ struct cmFindProgramHelper
return false;
});
}
- bool FileIsExecutable(std::string const& file) const
+ bool FileIsValid(std::string const& file) const
{
-#ifdef _WIN32
if (!this->FileIsExecutableCMP0109(file)) {
return false;
}
+#ifdef _WIN32
// Pretend the Windows "python" app installer alias does not exist.
if (cmSystemTools::LowerCase(file).find("/windowsapps/python") !=
std::string::npos) {
@@ -119,10 +121,8 @@ struct cmFindProgramHelper
return false;
}
}
- return true;
-#else
- return this->FileIsExecutableCMP0109(file);
#endif
+ return this->FindBase->Validate(file);
}
bool FileIsExecutableCMP0109(std::string const& file) const
{
diff --git a/Source/cmForEachCommand.cxx b/Source/cmForEachCommand.cxx
index b9400c9..3465c23 100644
--- a/Source/cmForEachCommand.cxx
+++ b/Source/cmForEachCommand.cxx
@@ -260,7 +260,7 @@ auto cmForEachFunctionBlocker::invoke(
cmExecutionStatus status(mf);
mf.ExecuteCommand(func, status);
if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
+ inStatus.SetReturnInvoked(status.GetReturnVariables());
result.Break = true;
break;
}
diff --git a/Source/cmFunctionBlocker.cxx b/Source/cmFunctionBlocker.cxx
index 40e692d..523482a 100644
--- a/Source/cmFunctionBlocker.cxx
+++ b/Source/cmFunctionBlocker.cxx
@@ -24,10 +24,11 @@ bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
auto self = mf.RemoveFunctionBlocker();
assert(self.get() == this);
- if (!this->ArgumentsMatch(lff, mf)) {
- cmListFileContext const& lfc = this->GetStartingContext();
- cmListFileContext closingContext =
- cmListFileContext::FromListFileFunction(lff, lfc.FilePath);
+ cmListFileContext const& lfc = this->GetStartingContext();
+ cmListFileContext closingContext =
+ cmListFileContext::FromListFileFunction(lff, lfc.FilePath);
+ if (this->EndCommandSupportsArguments() &&
+ !this->ArgumentsMatch(lff, mf)) {
std::ostringstream e;
/* clang-format off */
e << "A logical block opening on the line\n"
@@ -37,6 +38,15 @@ bool cmFunctionBlocker::IsFunctionBlocked(const cmListFileFunction& lff,
<< "with mis-matching arguments.";
/* clang-format on */
mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
+ } else if (!this->EndCommandSupportsArguments() &&
+ !lff.Arguments().empty()) {
+ std::ostringstream e;
+ /* clang-format off */
+ e << "A logical block closing on the line\n"
+ " " << closingContext << "\n"
+ "has unexpected arguments.";
+ /* clang-format on */
+ mf.IssueMessage(MessageType::AUTHOR_WARNING, e.str());
}
return this->Replay(std::move(this->Functions), status);
diff --git a/Source/cmFunctionBlocker.h b/Source/cmFunctionBlocker.h
index 38abeba..3e096f2 100644
--- a/Source/cmFunctionBlocker.h
+++ b/Source/cmFunctionBlocker.h
@@ -38,6 +38,8 @@ private:
virtual cm::string_view StartCommandName() const = 0;
virtual cm::string_view EndCommandName() const = 0;
+ virtual bool EndCommandSupportsArguments() const { return true; }
+
virtual bool ArgumentsMatch(cmListFileFunction const& lff,
cmMakefile& mf) const = 0;
diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx
index 1359009..f4768b6 100644
--- a/Source/cmFunctionCommand.cxx
+++ b/Source/cmFunctionCommand.cxx
@@ -120,6 +120,7 @@ bool cmFunctionHelperCommand::operator()(
return false;
}
if (status.GetReturnInvoked()) {
+ makefile.RaiseScope(status.GetReturnVariables());
break;
}
}
diff --git a/Source/cmGeneratedFileStream.cxx b/Source/cmGeneratedFileStream.cxx
index b529b8f..6212bbd 100644
--- a/Source/cmGeneratedFileStream.cxx
+++ b/Source/cmGeneratedFileStream.cxx
@@ -124,10 +124,10 @@ cmGeneratedFileStreamBase::~cmGeneratedFileStreamBase()
void cmGeneratedFileStreamBase::Open(std::string const& name)
{
// Save the original name of the file.
- this->Name = name;
+ this->Name = cmSystemTools::CollapseFullPath(name);
// Create the name of the temporary file.
- this->TempName = name;
+ this->TempName = this->Name;
#if defined(__VMS)
this->TempName += "_";
#else
@@ -231,7 +231,7 @@ int cmGeneratedFileStreamBase::RenameFile(std::string const& oldname,
void cmGeneratedFileStream::SetName(const std::string& fname)
{
- this->Name = fname;
+ this->Name = cmSystemTools::CollapseFullPath(fname);
}
void cmGeneratedFileStream::SetTempExt(std::string const& ext)
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 6235a2a..7f1e426 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -808,11 +808,16 @@ void handleSystemIncludesDep(cmLocalGenerator* lg,
dagChecker, depTgt, language),
result);
}
- if (!depTgt->IsImported() || excludeImported) {
+ if (!depTgt->GetPropertyAsBool("SYSTEM")) {
return;
}
- if (depTgt->GetPropertyAsBool("IMPORTED_NO_SYSTEM")) {
- return;
+ if (depTgt->IsImported()) {
+ if (excludeImported) {
+ return;
+ }
+ if (depTgt->GetPropertyAsBool("IMPORTED_NO_SYSTEM")) {
+ return;
+ }
}
if (cmValue dirs = depTgt->GetProperty("INTERFACE_INCLUDE_DIRECTORIES")) {
@@ -912,11 +917,19 @@ bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang,
return false;
}
- if (lang != "C" && lang != "CXX" && lang != "Fortran") {
+ if (lang != "C" && lang != "CXX" && lang != "CUDA" && lang != "Fortran") {
// We do not define IPO behavior for other languages.
return false;
}
+ if (lang == "CUDA") {
+ // CUDA IPO requires both CUDA_ARCHITECTURES and CUDA_SEPARABLE_COMPILATION
+ if (cmIsOff(this->GetSafeProperty("CUDA_ARCHITECTURES")) ||
+ cmIsOff(this->GetSafeProperty("CUDA_SEPARABLE_COMPILATION"))) {
+ return false;
+ }
+ }
+
cmPolicies::PolicyStatus cmp0069 = this->GetPolicyStatusCMP0069();
if (cmp0069 == cmPolicies::OLD || cmp0069 == cmPolicies::WARN) {
@@ -1708,7 +1721,8 @@ void addFileSetEntry(cmGeneratorTarget const* headTarget,
}
}
if (!found) {
- if (fileSet->GetType() == "HEADERS"_s) {
+ if (fileSet->GetType() == "HEADERS"_s ||
+ fileSet->GetType() == "CXX_MODULE_HEADER_UNITS"_s) {
headTarget->Makefile->GetOrCreateSourceGroup("Header Files")
->AddGroupFile(path);
}
@@ -1729,6 +1743,20 @@ void AddFileSetEntries(cmGeneratorTarget const* headTarget,
addFileSetEntry(headTarget, config, dagChecker, headerSet, entries);
}
}
+ for (auto const& entry : headTarget->Target->GetCxxModuleSetsEntries()) {
+ for (auto const& name : cmExpandedList(entry.Value)) {
+ auto const* cxxModuleSet = headTarget->Target->GetFileSet(name);
+ addFileSetEntry(headTarget, config, dagChecker, cxxModuleSet, entries);
+ }
+ }
+ for (auto const& entry :
+ headTarget->Target->GetCxxModuleHeaderSetsEntries()) {
+ for (auto const& name : cmExpandedList(entry.Value)) {
+ auto const* cxxModuleHeaderSet = headTarget->Target->GetFileSet(name);
+ addFileSetEntry(headTarget, config, dagChecker, cxxModuleHeaderSet,
+ entries);
+ }
+ }
}
bool processSources(cmGeneratorTarget const* tgt,
@@ -3409,7 +3437,9 @@ void cmGeneratorTarget::AddExplicitLanguageFlags(std::string& flags,
"EXPLICIT_LANGUAGE");
}
-void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
+void cmGeneratorTarget::AddCUDAArchitectureFlags(cmBuildStep compileOrLink,
+ const std::string& config,
+ std::string& flags) const
{
std::string property = this->GetSafeProperty("CUDA_ARCHITECTURES");
@@ -3441,6 +3471,7 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
std::string const& compiler =
this->Makefile->GetSafeDefinition("CMAKE_CUDA_COMPILER_ID");
+ const bool ipoEnabled = this->IsIPOEnabled("CUDA", config);
// Check for special modes: `all`, `all-major`.
if (property == "all" || property == "all-major") {
@@ -3520,6 +3551,13 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
}
if (compiler == "NVIDIA") {
+ if (ipoEnabled && compileOrLink == cmBuildStep::Link) {
+ if (cmValue cudaIPOFlags =
+ this->Makefile->GetDefinition("CMAKE_CUDA_LINK_OPTIONS_IPO")) {
+ flags += cudaIPOFlags;
+ }
+ }
+
for (CudaArchitecture& architecture : architectures) {
flags +=
" --generate-code=arch=compute_" + architecture.name + ",code=[";
@@ -3532,7 +3570,13 @@ void cmGeneratorTarget::AddCUDAArchitectureFlags(std::string& flags) const
}
}
- if (architecture.real) {
+ if (ipoEnabled) {
+ if (compileOrLink == cmBuildStep::Compile) {
+ flags += "lto_" + architecture.name;
+ } else if (compileOrLink == cmBuildStep::Link) {
+ flags += "sm_" + architecture.name;
+ }
+ } else if (architecture.real) {
flags += "sm_" + architecture.name;
}
@@ -8724,3 +8768,76 @@ std::string cmGeneratorTarget::GenerateHeaderSetVerificationFile(
return filename;
}
+
+bool cmGeneratorTarget::HaveCxx20ModuleSources() const
+{
+ auto const& fs_names = this->Target->GetAllFileSetNames();
+ return std::any_of(fs_names.begin(), fs_names.end(),
+ [this](std::string const& name) -> bool {
+ auto const* file_set = this->Target->GetFileSet(name);
+ if (!file_set) {
+ this->Makefile->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", this->Target->GetName(),
+ "\" is tracked to have file set \"", name,
+ "\", but it was not found."));
+ return false;
+ }
+
+ auto const& fs_type = file_set->GetType();
+ return fs_type == "CXX_MODULES"_s ||
+ fs_type == "CXX_MODULE_HEADER_UNITS"_s;
+ });
+}
+
+cmGeneratorTarget::Cxx20SupportLevel cmGeneratorTarget::HaveCxxModuleSupport(
+ std::string const& config) const
+{
+ auto const* state = this->Makefile->GetState();
+ if (!state->GetLanguageEnabled("CXX")) {
+ return Cxx20SupportLevel::MissingCxx;
+ }
+ cmStandardLevelResolver standardResolver(this->Makefile);
+ if (!standardResolver.HaveStandardAvailable(this, "CXX", config,
+ "cxx_std_20")) {
+ return Cxx20SupportLevel::NoCxx20;
+ }
+ if (!this->Makefile->IsOn("CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP")) {
+ return Cxx20SupportLevel::MissingExperimentalFlag;
+ }
+ return Cxx20SupportLevel::Supported;
+}
+
+void cmGeneratorTarget::CheckCxxModuleStatus(std::string const& config) const
+{
+ // Check for `CXX_MODULE*` file sets and a lack of support.
+ if (this->HaveCxx20ModuleSources()) {
+ switch (this->HaveCxxModuleSupport(config)) {
+ case cmGeneratorTarget::Cxx20SupportLevel::MissingCxx:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The \"", this->GetName(),
+ "\" target has C++ module sources but the \"CXX\" language "
+ "has not been enabled"));
+ break;
+ case cmGeneratorTarget::Cxx20SupportLevel::MissingExperimentalFlag:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The \"", this->GetName(),
+ "\" target has C++ module sources but its experimental "
+ "support has not been requested"));
+ break;
+ case cmGeneratorTarget::Cxx20SupportLevel::NoCxx20:
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "The \"", this->GetName(),
+ "\" target has C++ module sources but is not using at least "
+ "\"cxx_std_20\""));
+ break;
+ case cmGeneratorTarget::Cxx20SupportLevel::Supported:
+ // All is well.
+ break;
+ }
+ }
+}
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 6bce7d2..25e6a81 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -23,6 +23,7 @@
#include "cmStateTypes.h"
#include "cmValue.h"
+enum class cmBuildStep;
class cmComputeLinkInformation;
class cmCustomCommand;
class cmGlobalGenerator;
@@ -471,7 +472,9 @@ public:
void AddExplicitLanguageFlags(std::string& flags,
cmSourceFile const& sf) const;
- void AddCUDAArchitectureFlags(std::string& flags) const;
+ void AddCUDAArchitectureFlags(cmBuildStep compileOrLink,
+ const std::string& config,
+ std::string& flags) const;
void AddCUDAToolkitFlags(std::string& flags) const;
void AddHIPArchitectureFlags(std::string& flags) const;
@@ -1196,4 +1199,34 @@ public:
bool operator()(cmGeneratorTarget const* t1,
cmGeneratorTarget const* t2) const;
};
+
+ // C++20 module support queries.
+
+ /**
+ * Query whether the target expects C++20 module support.
+ *
+ * This will inspect the target itself to see if C++20 module
+ * support is expected to work based on its sources.
+ */
+ bool HaveCxx20ModuleSources() const;
+
+ enum class Cxx20SupportLevel
+ {
+ // C++ is not available.
+ MissingCxx,
+ // The experimental feature is not available.
+ MissingExperimentalFlag,
+ // The target does not require at least C++20.
+ NoCxx20,
+ // C++20 modules are available and working.
+ Supported,
+ };
+ /**
+ * Query whether the target has C++20 module support available (regardless of
+ * whether it is required or not).
+ */
+ Cxx20SupportLevel HaveCxxModuleSupport(std::string const& config) const;
+
+ // Check C++ module status for the target.
+ void CheckCxxModuleStatus(std::string const& config) const;
};
diff --git a/Source/cmGhsMultiTargetGenerator.cxx b/Source/cmGhsMultiTargetGenerator.cxx
index bf019c3..138d3f1 100644
--- a/Source/cmGhsMultiTargetGenerator.cxx
+++ b/Source/cmGhsMultiTargetGenerator.cxx
@@ -183,8 +183,8 @@ void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
auto i = this->FlagsByLanguage.find(language);
if (i == this->FlagsByLanguage.end()) {
std::string flags;
- this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
- language, config);
+ this->LocalGenerator->AddLanguageFlags(
+ flags, this->GeneratorTarget, cmBuildStep::Compile, language, config);
this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget,
language, config);
this->LocalGenerator->AddVisibilityPresetFlags(
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index 254220b..09aaa24 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -1854,6 +1854,15 @@ void cmGlobalGenerator::FinalizeTargetConfiguration()
cmExpandedList(standardIncludesStr);
standardIncludesSet.insert(standardIncludesVec.begin(),
standardIncludesVec.end());
+ if (li == "CUDA") {
+ std::string const& cudaSystemIncludeVar =
+ mf->GetSafeDefinition("CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES");
+ std::vector<std::string> cudaToolkitIncludeVec =
+ cmExpandedList(cudaSystemIncludeVar);
+ standardIncludesSet.insert(cudaToolkitIncludeVec.begin(),
+ cudaToolkitIncludeVec.end());
+ mf->AddIncludeDirectories(cudaToolkitIncludeVec);
+ }
}
mf->AddSystemIncludeDirectories(standardIncludesSet);
}
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index acaed36..c326ca6 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -3,8 +3,10 @@
#include "cmGlobalNinjaGenerator.h"
#include <algorithm>
+#include <cassert>
#include <cctype>
#include <cstdio>
+#include <functional>
#include <sstream>
#include <utility>
@@ -14,6 +16,7 @@
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/memory>
+#include <cmext/string_view>
#include <cm3p/json/reader.h>
#include <cm3p/json/value.h>
@@ -21,7 +24,9 @@
#include "cmsys/FStream.hxx"
+#include "cmCxxModuleMapper.h"
#include "cmDocumentationEntry.h"
+#include "cmFileSet.h"
#include "cmFortranParser.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpressionEvaluationFile.h"
@@ -2480,13 +2485,53 @@ cm::optional<cmSourceInfo> cmcmd_cmake_ninja_depends_fortran(
}
}
+struct CxxModuleFileSet
+{
+ std::string Name;
+ std::string RelativeDirectory;
+ std::string SourcePath;
+ std::string Type;
+ cmFileSetVisibility Visibility;
+ cm::optional<std::string> Destination;
+};
+
+struct CxxModuleBmiInstall
+{
+ std::string Component;
+ std::string Destination;
+ bool ExcludeFromAll;
+ bool Optional;
+ std::string Permissions;
+ std::string MessageLevel;
+ std::string ScriptLocation;
+};
+
+struct CxxModuleExport
+{
+ std::string Name;
+ std::string Destination;
+ std::string Prefix;
+ std::string CxxModuleInfoDir;
+ std::string Namespace;
+ bool Install;
+};
+
+struct cmGlobalNinjaGenerator::CxxModuleExportInfo
+{
+ std::map<std::string, CxxModuleFileSet> ObjectToFileSet;
+ cm::optional<CxxModuleBmiInstall> BmiInstallation;
+ std::vector<CxxModuleExport> Exports;
+ std::string Config;
+};
+
bool cmGlobalNinjaGenerator::WriteDyndepFile(
std::string const& dir_top_src, std::string const& dir_top_bld,
std::string const& dir_cur_src, std::string const& dir_cur_bld,
std::string const& arg_dd, std::vector<std::string> const& arg_ddis,
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
- std::string const& arg_lang, std::string const& arg_modmapfmt)
+ std::string const& arg_lang, std::string const& arg_modmapfmt,
+ CxxModuleExportInfo const& export_info)
{
// Setup path conversions.
{
@@ -2511,13 +2556,15 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
objects.push_back(std::move(info));
}
+ CxxModuleUsage usages;
+
// Map from module name to module file path, if known.
std::map<std::string, std::string> mod_files;
// Populate the module map with those provided by linked targets first.
for (std::string const& linked_target_dir : linked_target_dirs) {
std::string const ltmn =
- cmStrCat(linked_target_dir, "/", arg_lang, "Modules.json");
+ cmStrCat(linked_target_dir, '/', arg_lang, "Modules.json");
Json::Value ltm;
cmsys::ifstream ltmf(ltmn.c_str(), std::ios::in | std::ios::binary);
Json::Reader reader;
@@ -2528,21 +2575,71 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
return false;
}
if (ltm.isObject()) {
- for (Json::Value::iterator i = ltm.begin(); i != ltm.end(); ++i) {
- mod_files[i.key().asString()] = i->asString();
+ Json::Value const& target_modules = ltm["modules"];
+ if (target_modules.isObject()) {
+ for (auto i = target_modules.begin(); i != target_modules.end(); ++i) {
+ mod_files[i.key().asString()] = i->asString();
+ }
+ }
+ Json::Value const& target_modules_references = ltm["references"];
+ if (target_modules_references.isObject()) {
+ for (auto i = target_modules_references.begin();
+ i != target_modules_references.end(); ++i) {
+ if (i->isObject()) {
+ Json::Value const& reference_path = (*i)["path"];
+ CxxModuleReference module_reference;
+ if (reference_path.isString()) {
+ module_reference.Path = reference_path.asString();
+ }
+ Json::Value const& reference_method = (*i)["lookup-method"];
+ if (reference_method.isString()) {
+ std::string reference = reference_method.asString();
+ if (reference == "by-name") {
+ module_reference.Method = LookupMethod::ByName;
+ } else if (reference == "include-angle") {
+ module_reference.Method = LookupMethod::IncludeAngle;
+ } else if (reference == "include-quote") {
+ module_reference.Method = LookupMethod::IncludeQuote;
+ }
+ }
+ usages.Reference[i.key().asString()] = module_reference;
+ }
+ }
+ }
+ Json::Value const& target_modules_usage = ltm["usages"];
+ if (target_modules_usage.isObject()) {
+ for (auto i = target_modules_usage.begin();
+ i != target_modules_usage.end(); ++i) {
+ if (i->isArray()) {
+ for (auto j = i->begin(); j != i->end(); ++j) {
+ usages.Usage[i.key().asString()].insert(j->asString());
+ }
+ }
+ }
}
}
}
- const char* module_ext = "";
- if (arg_modmapfmt == "gcc") {
- module_ext = ".gcm";
+ cm::optional<CxxModuleMapFormat> modmap_fmt;
+ if (arg_modmapfmt.empty()) {
+ // nothing to do.
+ } else if (arg_modmapfmt == "gcc") {
+ modmap_fmt = CxxModuleMapFormat::Gcc;
+ } else if (arg_modmapfmt == "msvc") {
+ modmap_fmt = CxxModuleMapFormat::Msvc;
+ } else {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep does not understand the ", arg_modmapfmt,
+ " module map format"));
+ return false;
}
+ auto module_ext = CxxModuleMapExtension(modmap_fmt);
+
// Extend the module map with those provided by this target.
// We do this after loading the modules provided by linked targets
// in case we have one of the same name that must be preferred.
- Json::Value tm = Json::objectValue;
+ Json::Value target_modules = Json::objectValue;
for (cmScanDepInfo const& object : objects) {
for (auto const& p : object.Provides) {
std::string mod;
@@ -2555,12 +2652,13 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
}
} else {
// Assume the module file path matches the logical module name.
- std::string safe_logical_name = p.LogicalName;
+ std::string safe_logical_name =
+ p.LogicalName; // TODO: needs fixing for header units
cmSystemTools::ReplaceString(safe_logical_name, ":", "-");
mod = cmStrCat(module_dir, safe_logical_name, module_ext);
}
mod_files[p.LogicalName] = mod;
- tm[p.LogicalName] = mod;
+ target_modules[p.LogicalName] = mod;
}
}
@@ -2568,6 +2666,32 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
ddf << "ninja_dyndep_version = 1.0\n";
{
+ CxxModuleLocations locs;
+ locs.RootDirectory = ".";
+ locs.PathForGenerator = [this](std::string const& path) -> std::string {
+ return this->ConvertToNinjaPath(path);
+ };
+ locs.BmiLocationForModule =
+ [&mod_files](std::string const& logical) -> cm::optional<std::string> {
+ auto m = mod_files.find(logical);
+ if (m != mod_files.end()) {
+ return m->second;
+ }
+ return {};
+ };
+
+ // Insert information about the current target's modules.
+ if (modmap_fmt) {
+ auto cycle_modules = CxxModuleUsageSeed(locs, objects, usages);
+ if (!cycle_modules.empty()) {
+ cmSystemTools::Error(
+ cmStrCat("Circular dependency detected in the C++ module import "
+ "graph. See modules named: \"",
+ cmJoin(cycle_modules, R"(", ")"_s), '"'));
+ return false;
+ }
+ }
+
cmNinjaBuild build("dyndep");
build.Outputs.emplace_back("");
for (cmScanDepInfo const& object : objects) {
@@ -2589,60 +2713,332 @@ bool cmGlobalNinjaGenerator::WriteDyndepFile(
build.Variables.emplace("restat", "1");
}
- if (arg_modmapfmt.empty()) {
- // nothing to do.
- } else {
- std::stringstream mm;
- if (arg_modmapfmt == "gcc") {
- // Documented in GCC's documentation. The format is a series of lines
- // with a module name and the associated filename separated by
- // spaces. The first line may use `$root` as the module name to
- // specify a "repository root". That is used to anchor any relative
- // paths present in the file (CMake should never generate any).
-
- // Write the root directory to use for module paths.
- mm << "$root .\n";
-
- for (auto const& l : object.Provides) {
- auto m = mod_files.find(l.LogicalName);
- if (m != mod_files.end()) {
- mm << l.LogicalName << " " << this->ConvertToNinjaPath(m->second)
- << "\n";
- }
- }
- for (auto const& r : object.Requires) {
- auto m = mod_files.find(r.LogicalName);
- if (m != mod_files.end()) {
- mm << r.LogicalName << " " << this->ConvertToNinjaPath(m->second)
- << "\n";
- }
- }
- } else {
- cmSystemTools::Error(
- cmStrCat("-E cmake_ninja_dyndep does not understand the ",
- arg_modmapfmt, " module map format"));
- return false;
- }
+ if (modmap_fmt) {
+ auto mm = CxxModuleMapContent(*modmap_fmt, locs, object, usages);
// XXX(modmap): If changing this path construction, change
// `cmNinjaTargetGenerator::WriteObjectBuildStatements` to generate the
// corresponding file path.
cmGeneratedFileStream mmf(cmStrCat(object.PrimaryOutput, ".modmap"));
- mmf << mm.str();
+ mmf << mm;
}
this->WriteBuild(ddf, build);
}
}
+ Json::Value target_module_info = Json::objectValue;
+ target_module_info["modules"] = target_modules;
+
+ auto& target_usages = target_module_info["usages"] = Json::objectValue;
+ for (auto const& u : usages.Usage) {
+ auto& mod_usage = target_usages[u.first] = Json::arrayValue;
+ for (auto const& v : u.second) {
+ mod_usage.append(v);
+ }
+ }
+
+ auto name_for_method = [](LookupMethod method) -> cm::static_string_view {
+ switch (method) {
+ case LookupMethod::ByName:
+ return "by-name"_s;
+ case LookupMethod::IncludeAngle:
+ return "include-angle"_s;
+ case LookupMethod::IncludeQuote:
+ return "include-quote"_s;
+ }
+ assert(false && "unsupported lookup method");
+ return ""_s;
+ };
+
+ auto& target_references = target_module_info["references"] =
+ Json::objectValue;
+ for (auto const& r : usages.Reference) {
+ auto& mod_ref = target_references[r.first] = Json::objectValue;
+ mod_ref["path"] = r.second.Path;
+ mod_ref["lookup-method"] = std::string(name_for_method(r.second.Method));
+ }
+
// Store the map of modules provided by this target in a file for
// use by dependents that reference this target in linked-target-dirs.
std::string const target_mods_file = cmStrCat(
cmSystemTools::GetFilenamePath(arg_dd), '/', arg_lang, "Modules.json");
cmGeneratedFileStream tmf(target_mods_file);
- tmf << tm;
+ tmf << target_module_info;
+
+ bool result = true;
+
+ // Fortran doesn't support any of the file-set or BMI installation considered
+ // below.
+ if (arg_lang != "Fortran"_s) {
+ // Prepare the export information blocks.
+ std::string const config_upper =
+ cmSystemTools::UpperCase(export_info.Config);
+ std::vector<std::pair<std::unique_ptr<cmGeneratedFileStream>,
+ CxxModuleExport const*>>
+ exports;
+ for (auto const& exp : export_info.Exports) {
+ std::unique_ptr<cmGeneratedFileStream> properties;
+
+ std::string const export_dir =
+ cmStrCat(exp.Prefix, '/', exp.CxxModuleInfoDir, '/');
+ std::string const property_file_path = cmStrCat(
+ export_dir, "target-", exp.Name, '-', export_info.Config, ".cmake");
+ properties = cm::make_unique<cmGeneratedFileStream>(property_file_path);
+
+ // Set up the preamble.
+ *properties << "set_property(TARGET \"" << exp.Namespace << exp.Name
+ << "\"\n"
+ << " PROPERTY IMPORTED_CXX_MODULES_" << config_upper
+ << '\n';
+
+ exports.emplace_back(std::move(properties), &exp);
+ }
+
+ std::unique_ptr<cmGeneratedFileStream> bmi_install_script;
+ if (export_info.BmiInstallation) {
+ bmi_install_script = cm::make_unique<cmGeneratedFileStream>(
+ export_info.BmiInstallation->ScriptLocation);
+ }
+
+ auto cmEscape = [](cm::string_view str) {
+ return cmOutputConverter::EscapeForCMake(
+ str, cmOutputConverter::WrapQuotes::NoWrap);
+ };
+ auto install_destination =
+ [&cmEscape](std::string const& dest) -> std::pair<bool, std::string> {
+ if (cmSystemTools::FileIsFullPath(dest)) {
+ return std::make_pair(true, cmEscape(dest));
+ }
+ return std::make_pair(false,
+ cmStrCat("${_IMPORT_PREFIX}/", cmEscape(dest)));
+ };
- return true;
+ // public/private requirement tracking.
+ std::set<std::string> private_modules;
+ std::map<std::string, std::set<std::string>> public_source_requires;
+
+ for (cmScanDepInfo const& object : objects) {
+ // Convert to forward slashes.
+ auto output_path = object.PrimaryOutput;
+# ifdef _WIN32
+ cmSystemTools::ConvertToUnixSlashes(output_path);
+# endif
+ // Find the fileset for this object.
+ auto fileset_info_itr = export_info.ObjectToFileSet.find(output_path);
+ bool const has_provides = !object.Provides.empty();
+ if (fileset_info_itr == export_info.ObjectToFileSet.end()) {
+ // If it provides anything, it should have a `CXX_MODULES` or
+ // `CXX_MODULE_INTERNAL_PARTITIONS` type and be present.
+ if (has_provides) {
+ // Take the first module provided to provide context.
+ auto const& provides = object.Provides[0];
+ char const* ok_types = "`CXX_MODULES`";
+ if (provides.LogicalName.find(':') != std::string::npos) {
+ ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
+ "it is not `export`ed)";
+ }
+ cmSystemTools::Error(
+ cmStrCat("Output ", object.PrimaryOutput, " provides the `",
+ provides.LogicalName,
+ "` module but it is not found in a `FILE_SET` of type ",
+ ok_types));
+ result = false;
+ }
+
+ // This object file does not provide anything, so nothing more needs to
+ // be done.
+ continue;
+ }
+
+ auto const& file_set = fileset_info_itr->second;
+
+ // Verify the fileset type for the object.
+ if (file_set.Type == "CXX_MODULES"_s) {
+ if (!has_provides) {
+ cmSystemTools::Error(cmStrCat(
+ "Output ", object.PrimaryOutput,
+ " is of type `CXX_MODULES` but does not provide a module"));
+ result = false;
+ continue;
+ }
+ } else if (file_set.Type == "CXX_MODULE_INTERNAL_PARTITIONS"_s) {
+ if (!has_provides) {
+ cmSystemTools::Error(cmStrCat(
+ "Source ", file_set.SourcePath,
+ " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
+ "provide a module"));
+ result = false;
+ continue;
+ }
+ auto const& provides = object.Provides[0];
+ if (provides.LogicalName.find(':') == std::string::npos) {
+ cmSystemTools::Error(cmStrCat(
+ "Source ", file_set.SourcePath,
+ " is of type `CXX_MODULE_INTERNAL_PARTITIONS` but does not "
+ "provide a module partition"));
+ result = false;
+ continue;
+ }
+ } else if (file_set.Type == "CXX_MODULE_HEADERS"_s) {
+ // TODO.
+ } else {
+ if (has_provides) {
+ auto const& provides = object.Provides[0];
+ char const* ok_types = "`CXX_MODULES`";
+ if (provides.LogicalName.find(':') != std::string::npos) {
+ ok_types = "`CXX_MODULES` (or `CXX_MODULE_INTERNAL_PARTITIONS` if "
+ "it is not `export`ed)";
+ }
+ cmSystemTools::Error(cmStrCat(
+ "Source ", file_set.SourcePath, " provides the `",
+ provides.LogicalName, "` C++ module but is of type `",
+ file_set.Type, "` module but must be of type ", ok_types));
+ result = false;
+ }
+
+ // Not a C++ module; ignore.
+ continue;
+ }
+
+ if (!cmFileSetVisibilityIsForInterface(file_set.Visibility)) {
+ // Nothing needs to be conveyed about non-`PUBLIC` modules.
+ for (auto const& p : object.Provides) {
+ private_modules.insert(p.LogicalName);
+ }
+ continue;
+ }
+
+ // The module is public. Record what it directly requires.
+ {
+ auto& reqs = public_source_requires[file_set.SourcePath];
+ for (auto const& r : object.Requires) {
+ reqs.insert(r.LogicalName);
+ }
+ }
+
+ // Write out properties and install rules for any exports.
+ for (auto const& p : object.Provides) {
+ bool bmi_dest_is_abs = false;
+ std::string bmi_destination;
+ if (export_info.BmiInstallation) {
+ auto dest =
+ install_destination(export_info.BmiInstallation->Destination);
+ bmi_dest_is_abs = dest.first;
+ bmi_destination = cmStrCat(dest.second, '/');
+ }
+
+ std::string install_bmi_path;
+ std::string build_bmi_path;
+ auto m = mod_files.find(p.LogicalName);
+ if (m != mod_files.end()) {
+ install_bmi_path =
+ cmStrCat(bmi_destination,
+ cmEscape(cmSystemTools::GetFilenameName(m->second)));
+ build_bmi_path = cmEscape(m->second);
+ }
+
+ for (auto const& exp : exports) {
+ std::string iface_source;
+ if (exp.second->Install && file_set.Destination) {
+ auto dest = install_destination(*file_set.Destination);
+ iface_source = cmStrCat(
+ dest.second, '/', cmEscape(file_set.RelativeDirectory),
+ cmEscape(cmSystemTools::GetFilenameName(file_set.SourcePath)));
+ } else {
+ iface_source = cmEscape(file_set.SourcePath);
+ }
+
+ std::string bmi_path;
+ if (exp.second->Install && export_info.BmiInstallation) {
+ bmi_path = install_bmi_path;
+ } else if (!exp.second->Install) {
+ bmi_path = build_bmi_path;
+ }
+
+ if (iface_source.empty()) {
+ // No destination for the C++ module source; ignore this property
+ // value.
+ continue;
+ }
+
+ *exp.first << " \"" << cmEscape(p.LogicalName) << '='
+ << iface_source;
+ if (!bmi_path.empty()) {
+ *exp.first << ',' << bmi_path;
+ }
+ *exp.first << "\"\n";
+ }
+
+ if (bmi_install_script) {
+ auto const& bmi_install = *export_info.BmiInstallation;
+
+ *bmi_install_script << "if (CMAKE_INSTALL_COMPONENT STREQUAL \""
+ << cmEscape(bmi_install.Component) << '\"';
+ if (!bmi_install.ExcludeFromAll) {
+ *bmi_install_script << " OR NOT CMAKE_INSTALL_COMPONENT";
+ }
+ *bmi_install_script << ")\n";
+ *bmi_install_script << " file(INSTALL\n"
+ " DESTINATION \"";
+ if (!bmi_dest_is_abs) {
+ *bmi_install_script << "${CMAKE_INSTALL_PREFIX}/";
+ }
+ *bmi_install_script << cmEscape(bmi_install.Destination)
+ << "\"\n"
+ " TYPE FILE\n";
+ if (bmi_install.Optional) {
+ *bmi_install_script << " OPTIONAL\n";
+ }
+ if (!bmi_install.MessageLevel.empty()) {
+ *bmi_install_script << " " << bmi_install.MessageLevel << "\n";
+ }
+ if (!bmi_install.Permissions.empty()) {
+ *bmi_install_script << " PERMISSIONS" << bmi_install.Permissions
+ << "\n";
+ }
+ *bmi_install_script << " FILES \"" << m->second << "\")\n";
+ if (bmi_dest_is_abs) {
+ *bmi_install_script
+ << " list(APPEND CMAKE_ABSOLUTE_DESTINATION_FILES\n"
+ " \""
+ << cmEscape(cmSystemTools::GetFilenameName(m->second))
+ << "\")\n"
+ " if (CMAKE_WARN_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
+ " message(WARNING\n"
+ " \"ABSOLUTE path INSTALL DESTINATION : "
+ "${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
+ " endif ()\n"
+ " if (CMAKE_ERROR_ON_ABSOLUTE_INSTALL_DESTINATION)\n"
+ " message(FATAL_ERROR\n"
+ " \"ABSOLUTE path INSTALL DESTINATION forbidden (by "
+ "caller): ${CMAKE_ABSOLUTE_DESTINATION_FILES}\")\n"
+ " endif ()\n";
+ }
+ *bmi_install_script << "endif ()\n";
+ }
+ }
+ }
+
+ // Add trailing parenthesis for the `set_property` call.
+ for (auto const& exp : exports) {
+ *exp.first << ")\n";
+ }
+
+ // Check that public sources only require public modules.
+ for (auto const& pub_reqs : public_source_requires) {
+ for (auto const& req : pub_reqs.second) {
+ if (private_modules.count(req)) {
+ cmSystemTools::Error(cmStrCat(
+ "Public C++ module source `", pub_reqs.first, "` requires the `",
+ req, "` C++ module which is provided by a private source"));
+ result = false;
+ }
+ }
+ }
+ }
+
+ return result;
}
int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
@@ -2716,6 +3112,59 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
}
}
+ cmGlobalNinjaGenerator::CxxModuleExportInfo export_info;
+ export_info.Config = tdi["config"].asString();
+ if (export_info.Config.empty()) {
+ export_info.Config = "noconfig";
+ }
+ Json::Value const& tdi_exports = tdi["exports"];
+ if (tdi_exports.isArray()) {
+ for (auto const& tdi_export : tdi_exports) {
+ CxxModuleExport exp;
+ exp.Install = tdi_export["install"].asBool();
+ exp.Name = tdi_export["export-name"].asString();
+ exp.Destination = tdi_export["destination"].asString();
+ exp.Prefix = tdi_export["export-prefix"].asString();
+ exp.CxxModuleInfoDir = tdi_export["cxx-module-info-dir"].asString();
+ exp.Namespace = tdi_export["namespace"].asString();
+
+ export_info.Exports.push_back(exp);
+ }
+ }
+ auto const& bmi_installation = tdi["bmi-installation"];
+ if (bmi_installation.isObject()) {
+ CxxModuleBmiInstall bmi_install;
+
+ bmi_install.Component = bmi_installation["component"].asString();
+ bmi_install.Destination = bmi_installation["destination"].asString();
+ bmi_install.ExcludeFromAll = bmi_installation["exclude-from-all"].asBool();
+ bmi_install.Optional = bmi_installation["optional"].asBool();
+ bmi_install.Permissions = bmi_installation["permissions"].asString();
+ bmi_install.MessageLevel = bmi_installation["message-level"].asString();
+ bmi_install.ScriptLocation =
+ bmi_installation["script-location"].asString();
+
+ export_info.BmiInstallation = bmi_install;
+ }
+ Json::Value const& tdi_cxx_modules = tdi["cxx-modules"];
+ if (tdi_cxx_modules.isObject()) {
+ for (auto i = tdi_cxx_modules.begin(); i != tdi_cxx_modules.end(); ++i) {
+ CxxModuleFileSet& fsi = export_info.ObjectToFileSet[i.key().asString()];
+ auto const& tdi_cxx_module_info = *i;
+ fsi.Name = tdi_cxx_module_info["name"].asString();
+ fsi.RelativeDirectory =
+ tdi_cxx_module_info["relative-directory"].asString();
+ fsi.SourcePath = tdi_cxx_module_info["source"].asString();
+ fsi.Type = tdi_cxx_module_info["type"].asString();
+ fsi.Visibility = cmFileSetVisibilityFromName(
+ tdi_cxx_module_info["visibility"].asString(), nullptr);
+ auto const& tdi_fs_dest = tdi_cxx_module_info["destination"];
+ if (tdi_fs_dest.isString()) {
+ fsi.Destination = tdi_fs_dest.asString();
+ }
+ }
+ }
+
cmake cm(cmake::RoleInternal, cmState::Unknown);
cm.SetHomeDirectory(dir_top_src);
cm.SetHomeOutputDirectory(dir_top_bld);
@@ -2723,7 +3172,8 @@ int cmcmd_cmake_ninja_dyndep(std::vector<std::string>::const_iterator argBeg,
if (!ggd ||
!cm::static_reference_cast<cmGlobalNinjaGenerator>(ggd).WriteDyndepFile(
dir_top_src, dir_top_bld, dir_cur_src, dir_cur_bld, arg_dd, arg_ddis,
- module_dir, linked_target_dirs, arg_lang, arg_modmapfmt)) {
+ module_dir, linked_target_dirs, arg_lang, arg_modmapfmt,
+ export_info)) {
return 1;
}
return 0;
diff --git a/Source/cmGlobalNinjaGenerator.h b/Source/cmGlobalNinjaGenerator.h
index aa2df4d..dc4f444 100644
--- a/Source/cmGlobalNinjaGenerator.h
+++ b/Source/cmGlobalNinjaGenerator.h
@@ -417,13 +417,15 @@ public:
bool HasOutputPathPrefix() const { return !this->OutputPathPrefix.empty(); }
void StripNinjaOutputPathPrefixAsSuffix(std::string& path);
+ struct CxxModuleExportInfo;
bool WriteDyndepFile(
std::string const& dir_top_src, std::string const& dir_top_bld,
std::string const& dir_cur_src, std::string const& dir_cur_bld,
std::string const& arg_dd, std::vector<std::string> const& arg_ddis,
std::string const& module_dir,
std::vector<std::string> const& linked_target_dirs,
- std::string const& arg_lang, std::string const& arg_modmapfmt);
+ std::string const& arg_lang, std::string const& arg_modmapfmt,
+ CxxModuleExportInfo const& export_info);
virtual std::string BuildAlias(const std::string& alias,
const std::string& /*config*/) const
diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx
index 29eeb5a..7886fc7 100644
--- a/Source/cmGlobalVisualStudio10Generator.cxx
+++ b/Source/cmGlobalVisualStudio10Generator.cxx
@@ -389,6 +389,27 @@ bool cmGlobalVisualStudio10Generator::SetGeneratorToolset(
this->GeneratorToolsetVersion.clear();
this->GeneratorToolsetVersionProps = {};
} break;
+ case AuxToolset::PropsIndeterminate: {
+ std::ostringstream e;
+ /* clang-format off */
+ e <<
+ "Generator\n"
+ " " << this->GetName() << "\n"
+ "given toolset and version specification\n"
+ " " << this->GetPlatformToolsetString() << ",version=" <<
+ this->GeneratorToolsetVersion << "\n"
+ "has multiple matches installed at\n" <<
+ " " << auxProps << "\n" <<
+ "The toolset and version specification must resolve \n" <<
+ "to a single installed toolset";
+ ;
+ /* clang-format on */
+ mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
+
+ // Clear the configured tool-set
+ this->GeneratorToolsetVersion.clear();
+ this->GeneratorToolsetVersionProps = {};
+ } break;
}
}
diff --git a/Source/cmGlobalVisualStudio10Generator.h b/Source/cmGlobalVisualStudio10Generator.h
index 4977a84..a33c94e 100644
--- a/Source/cmGlobalVisualStudio10Generator.h
+++ b/Source/cmGlobalVisualStudio10Generator.h
@@ -200,7 +200,8 @@ protected:
None,
Default,
PropsExist,
- PropsMissing
+ PropsMissing,
+ PropsIndeterminate
};
virtual AuxToolset FindAuxToolset(std::string& version,
std::string& props) const;
diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx
index f7f7317..e53ae8e 100644
--- a/Source/cmGlobalVisualStudio7Generator.cxx
+++ b/Source/cmGlobalVisualStudio7Generator.cxx
@@ -395,12 +395,27 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
{
VisualStudioFolders.clear();
+ std::vector<std::string> configs =
+ root->GetMakefile()->GetGeneratorConfigs(cmMakefile::ExcludeEmptyConfig);
+
for (cmGeneratorTarget const* target : projectTargets) {
if (!this->IsInSolution(target)) {
continue;
}
bool written = false;
+ for (auto const& c : configs) {
+ target->CheckCxxModuleStatus(c);
+ }
+
+ if (target->HaveCxx20ModuleSources() && !this->SupportsCxxModuleDyndep()) {
+ root->GetMakefile()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The \"", target->GetName(),
+ "\" target contains C++ module sources which are not "
+ "supported by the generator"));
+ }
+
// handle external vc project files
cmValue expath = target->GetProperty("EXTERNAL_MSPROJECT");
if (expath) {
diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h
index a55cf45..288069c 100644
--- a/Source/cmGlobalVisualStudio7Generator.h
+++ b/Source/cmGlobalVisualStudio7Generator.h
@@ -157,6 +157,8 @@ protected:
cmValue typeGuid,
const std::set<BT<std::pair<std::string, bool>>>& dependencies) = 0;
+ virtual bool SupportsCxxModuleDyndep() const { return false; }
+
std::string ConvertToSolutionPath(const std::string& path);
std::set<std::string> IsPartOfDefaultBuild(
diff --git a/Source/cmGlobalVisualStudioVersionedGenerator.cxx b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
index 7e36881..c3ba2c2 100644
--- a/Source/cmGlobalVisualStudioVersionedGenerator.cxx
+++ b/Source/cmGlobalVisualStudioVersionedGenerator.cxx
@@ -770,12 +770,15 @@ cmGlobalVisualStudioVersionedGenerator::FindAuxToolset(
cmSystemTools::ConvertToUnixSlashes(instancePath);
// Translate three-component format accepted by "vcvarsall -vcvars_ver=".
- cmsys::RegularExpression threeComponent(
+ cmsys::RegularExpression threeComponentRegex(
"^([0-9]+\\.[0-9]+)\\.[0-9][0-9][0-9][0-9][0-9]$");
- if (threeComponent.find(version)) {
+ // The two-component format represents the two major components of the
+ // three-component format
+ cmsys::RegularExpression twoComponentRegex("^([0-9]+\\.[0-9]+)$");
+ if (threeComponentRegex.find(version)) {
// Load "VC/Auxiliary/Build/*/Microsoft.VCToolsVersion.*.txt" files
// with two matching components to check their three-component version.
- std::string const& twoComponent = threeComponent.match(1);
+ std::string const& twoComponent = threeComponentRegex.match(1);
std::string pattern =
cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, twoComponent,
"*/Microsoft.VCToolsVersion."_s, twoComponent, "*.txt"_s);
@@ -801,6 +804,34 @@ cmGlobalVisualStudioVersionedGenerator::FindAuxToolset(
}
}
}
+ } else if (twoComponentRegex.find(version)) {
+ std::string const& twoComponent = twoComponentRegex.match(1);
+ std::string pattern =
+ cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s, twoComponent,
+ "*/Microsoft.VCToolsVersion."_s, twoComponent, "*.txt"_s);
+ cmsys::Glob glob;
+ glob.SetRecurseThroughSymlinks(false);
+ // Since we are only using the first two components of the toolset version,
+ // we require a definite match
+ if (glob.FindFiles(pattern) && glob.GetFiles().size() == 1) {
+ std::string const& txt = glob.GetFiles()[0];
+ std::string ver;
+ cmsys::ifstream fin(txt.c_str());
+ if (fin && std::getline(fin, ver)) {
+ // Strip trailing whitespace.
+ ver = ver.substr(0, ver.find_first_not_of("0123456789."));
+ // We assume the version is correct, since it is the only one that
+ // matched.
+ cmsys::RegularExpression extractVersion(
+ "VCToolsVersion\\.([0-9.]+)\\.txt$");
+ if (extractVersion.find(txt)) {
+ version = extractVersion.match(1);
+ }
+ }
+ } else {
+ props = cmStrCat(instancePath, "/VC/Auxiliary/Build/"_s);
+ return AuxToolset::PropsIndeterminate;
+ }
}
if (cmSystemTools::VersionCompareGreaterEq(version, "14.20")) {
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index b9bbb67..eb85b47 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -468,6 +468,10 @@ bool cmGlobalXCodeGenerator::Open(const std::string& bindir,
}
CFRelease(cfStr);
}
+#else
+ (void)bindir;
+ (void)projectName;
+ (void)dryRun;
#endif
return ret;
@@ -1372,6 +1376,18 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
return true;
}
+ for (std::string const& configName : this->CurrentConfigurationTypes) {
+ gtgt->CheckCxxModuleStatus(configName);
+ }
+
+ if (gtgt->HaveCxx20ModuleSources()) {
+ gtgt->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The \"", gtgt->GetName(),
+ "\" target contains C++ module sources which are not "
+ "supported by the generator"));
+ }
+
auto& gtgt_visited = this->CommandsVisited[gtgt];
auto& deps = this->GetTargetDirectDepends(gtgt);
for (auto& d : deps) {
@@ -2352,8 +2368,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
std::string& flags = cflags[lang];
// Add language-specific flags.
- this->CurrentLocalGenerator->AddLanguageFlags(flags, gtgt, lang,
- configName);
+ this->CurrentLocalGenerator->AddLanguageFlags(
+ flags, gtgt, cmBuildStep::Compile, lang, configName);
if (gtgt->IsIPOEnabled(lang, configName)) {
this->CurrentLocalGenerator->AppendFeatureOptions(flags, lang, "IPO");
@@ -2407,6 +2423,18 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
this->AppendDefines(ppDefs, targetDefines);
buildSettings->AddAttribute("GCC_PREPROCESSOR_DEFINITIONS",
ppDefs.CreateList());
+ if (languages.count("Swift")) {
+ if (this->XcodeVersion < 80) {
+ std::string defineString;
+ std::set<std::string> defines(targetDefines.begin(),
+ targetDefines.end());
+ this->CurrentLocalGenerator->JoinDefines(defines, defineString, "Swift");
+ cflags["Swift"] += " " + defineString;
+ } else {
+ buildSettings->AddAttribute("SWIFT_ACTIVE_COMPILATION_CONDITIONS",
+ ppDefs.CreateList());
+ }
+ }
std::string extraLinkOptionsVar;
std::string extraLinkOptions;
@@ -2866,8 +2894,8 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
}
// Create the INSTALL_PATH attribute.
- std::string install_name_dir;
if (gtgt->GetType() == cmStateEnums::SHARED_LIBRARY) {
+ std::string install_name_dir;
// Get the install_name directory for the build tree.
install_name_dir = gtgt->GetInstallNameDirForBuildTree(configName);
// Xcode doesn't create the correct install_name in some cases.
@@ -2889,9 +2917,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
extraLinkOptions += " -install_name ";
extraLinkOptions += XCodeEscapePath(install_name);
}
+ buildSettings->AddAttribute("INSTALL_PATH",
+ this->CreateString(install_name_dir));
}
- buildSettings->AddAttribute("INSTALL_PATH",
- this->CreateString(install_name_dir));
// Create the LD_RUNPATH_SEARCH_PATHS
cmComputeLinkInformation* pcli = gtgt->GetLinkInformation(configName);
diff --git a/Source/cmIfCommand.cxx b/Source/cmIfCommand.cxx
index 0da72b1..c2a09c1 100644
--- a/Source/cmIfCommand.cxx
+++ b/Source/cmIfCommand.cxx
@@ -150,7 +150,7 @@ bool cmIfFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
cmExecutionStatus status(mf);
mf.ExecuteCommand(func, status);
if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
+ inStatus.SetReturnInvoked(status.GetReturnVariables());
return true;
}
if (status.GetBreakInvoked()) {
diff --git a/Source/cmInstallCommand.cxx b/Source/cmInstallCommand.cxx
index 7ca5b23..82adca8 100644
--- a/Source/cmInstallCommand.cxx
+++ b/Source/cmInstallCommand.cxx
@@ -12,18 +12,22 @@
#include <utility>
#include <cm/memory>
+#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmsys/Glob.hxx"
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
#include "cmExecutionStatus.h"
+#include "cmExperimental.h"
#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
#include "cmInstallCommandArguments.h"
+#include "cmInstallCxxModuleBmiGenerator.h"
#include "cmInstallDirectoryGenerator.h"
#include "cmInstallExportGenerator.h"
#include "cmInstallFileSetGenerator.h"
@@ -54,13 +58,13 @@ namespace {
struct RuntimeDependenciesArgs
{
- std::vector<std::string> Directories;
- std::vector<std::string> PreIncludeRegexes;
- std::vector<std::string> PreExcludeRegexes;
- std::vector<std::string> PostIncludeRegexes;
- std::vector<std::string> PostExcludeRegexes;
- std::vector<std::string> PostIncludeFiles;
- std::vector<std::string> PostExcludeFiles;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Directories;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PreIncludeRegexes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PreExcludeRegexes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeRegexes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeRegexes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PostIncludeFiles;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PostExcludeFiles;
};
auto const RuntimeDependenciesArgHelper =
@@ -109,6 +113,8 @@ public:
const cmInstallCommandArguments* args) const;
std::string GetLibraryDestination(
const cmInstallCommandArguments* args) const;
+ std::string GetCxxModulesBmiDestination(
+ const cmInstallCommandArguments* args) const;
std::string GetIncludeDestination(
const cmInstallCommandArguments* args) const;
std::string GetSysconfDestination(
@@ -401,16 +407,17 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
struct ArgVectors
{
- std::vector<std::string> Archive;
- std::vector<std::string> Library;
- std::vector<std::string> Runtime;
- std::vector<std::string> Object;
- std::vector<std::string> Framework;
- std::vector<std::string> Bundle;
- std::vector<std::string> Includes;
- std::vector<std::string> PrivateHeader;
- std::vector<std::string> PublicHeader;
- std::vector<std::string> Resource;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Archive;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Library;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Runtime;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Object;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Framework;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Bundle;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Includes;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PrivateHeader;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> PublicHeader;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Resource;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> CxxModulesBmi;
std::vector<std::vector<std::string>> FileSets;
};
@@ -426,7 +433,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
.Bind("PRIVATE_HEADER"_s, &ArgVectors::PrivateHeader)
.Bind("PUBLIC_HEADER"_s, &ArgVectors::PublicHeader)
.Bind("RESOURCE"_s, &ArgVectors::Resource)
- .Bind("FILE_SET"_s, &ArgVectors::FileSets);
+ .Bind("FILE_SET"_s, &ArgVectors::FileSets)
+ .Bind("CXX_MODULES_BMI"_s, &ArgVectors::CxxModulesBmi);
std::vector<std::string> genericArgVector;
ArgVectors const argVectors = argHelper.Parse(args, &genericArgVector);
@@ -434,26 +442,25 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
// now parse the generic args (i.e. the ones not specialized on LIBRARY/
// ARCHIVE, RUNTIME etc. (see above)
// These generic args also contain the targets and the export stuff
- std::vector<std::string> targetList;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> targetList;
std::string exports;
- std::vector<std::string> runtimeDependenciesArgVector;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>>
+ runtimeDependenciesArgVector;
std::string runtimeDependencySetArg;
std::vector<std::string> unknownArgs;
- std::vector<std::string> parsedArgs;
cmInstallCommandArguments genericArgs(helper.DefaultComponentName);
genericArgs.Bind("TARGETS"_s, targetList);
genericArgs.Bind("EXPORT"_s, exports);
genericArgs.Bind("RUNTIME_DEPENDENCIES"_s, runtimeDependenciesArgVector);
genericArgs.Bind("RUNTIME_DEPENDENCY_SET"_s, runtimeDependencySetArg);
- genericArgs.Parse(genericArgVector, &unknownArgs, nullptr, &parsedArgs);
+ genericArgs.Parse(genericArgVector, &unknownArgs);
bool success = genericArgs.Finalize();
- bool withRuntimeDependencies =
- std::find(parsedArgs.begin(), parsedArgs.end(), "RUNTIME_DEPENDENCIES") !=
- parsedArgs.end();
RuntimeDependenciesArgs runtimeDependenciesArgs =
- RuntimeDependenciesArgHelper.Parse(runtimeDependenciesArgVector,
- &unknownArgs);
+ runtimeDependenciesArgVector
+ ? RuntimeDependenciesArgHelper.Parse(*runtimeDependenciesArgVector,
+ &unknownArgs)
+ : RuntimeDependenciesArgs();
cmInstallCommandArguments archiveArgs(helper.DefaultComponentName);
cmInstallCommandArguments libraryArgs(helper.DefaultComponentName);
@@ -467,6 +474,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
cmInstallCommandIncludesArgument includesArgs;
std::vector<cmInstallCommandFileSetArguments> fileSetArgs(
argVectors.FileSets.size(), { helper.DefaultComponentName });
+ cmInstallCommandArguments cxxModuleBmiArgs(helper.DefaultComponentName);
// now parse the args for specific parts of the target (e.g. LIBRARY,
// RUNTIME, ARCHIVE etc.
@@ -490,6 +498,15 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
fileSetArgs[i] = std::move(fileSetArg);
}
+ bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
+ *helper.Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
+ if (!supportCxx20FileSetTypes) {
+ std::copy(argVectors.CxxModulesBmi.begin(), argVectors.CxxModulesBmi.end(),
+ std::back_inserter(unknownArgs));
+ } else {
+ cxxModuleBmiArgs.Parse(argVectors.CxxModulesBmi, &unknownArgs);
+ }
+
if (!unknownArgs.empty()) {
// Unknown argument.
status.SetError(
@@ -510,6 +527,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
for (auto& fileSetArg : fileSetArgs) {
fileSetArg.SetGenericArguments(&genericArgs);
}
+ cxxModuleBmiArgs.SetGenericArguments(&genericArgs);
success = success && archiveArgs.Finalize();
success = success && libraryArgs.Finalize();
@@ -523,6 +541,9 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
for (auto& fileSetArg : fileSetArgs) {
success = success && fileSetArg.Finalize();
}
+ if (supportCxx20FileSetTypes) {
+ success = success && cxxModuleBmiArgs.Finalize();
+ }
if (!success) {
return false;
@@ -536,7 +557,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
publicHeaderArgs.GetNamelinkOnly() || resourceArgs.GetNamelinkOnly() ||
std::any_of(fileSetArgs.begin(), fileSetArgs.end(),
[](const cmInstallCommandFileSetArguments& fileSetArg)
- -> bool { return fileSetArg.GetNamelinkOnly(); })) {
+ -> bool { return fileSetArg.GetNamelinkOnly(); }) ||
+ cxxModuleBmiArgs.GetNamelinkOnly()) {
status.SetError(
"TARGETS given NAMELINK_ONLY option not in LIBRARY group. "
"The NAMELINK_ONLY option may be specified only following LIBRARY.");
@@ -548,7 +570,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
publicHeaderArgs.GetNamelinkSkip() || resourceArgs.GetNamelinkSkip() ||
std::any_of(fileSetArgs.begin(), fileSetArgs.end(),
[](const cmInstallCommandFileSetArguments& fileSetArg)
- -> bool { return fileSetArg.GetNamelinkSkip(); })) {
+ -> bool { return fileSetArg.GetNamelinkSkip(); }) ||
+ cxxModuleBmiArgs.GetNamelinkSkip()) {
status.SetError(
"TARGETS given NAMELINK_SKIP option not in LIBRARY group. "
"The NAMELINK_SKIP option may be specified only following LIBRARY.");
@@ -564,7 +587,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
resourceArgs.HasNamelinkComponent() ||
std::any_of(fileSetArgs.begin(), fileSetArgs.end(),
[](const cmInstallCommandFileSetArguments& fileSetArg)
- -> bool { return fileSetArg.HasNamelinkComponent(); })) {
+ -> bool { return fileSetArg.HasNamelinkComponent(); }) ||
+ cxxModuleBmiArgs.HasNamelinkComponent()) {
status.SetError(
"TARGETS given NAMELINK_COMPONENT option not in LIBRARY group. "
"The NAMELINK_COMPONENT option may be specified only following "
@@ -583,7 +607,8 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
!publicHeaderArgs.GetType().empty() || !resourceArgs.GetType().empty() ||
std::any_of(fileSetArgs.begin(), fileSetArgs.end(),
[](const cmInstallCommandFileSetArguments& fileSetArg)
- -> bool { return !fileSetArg.GetType().empty(); })) {
+ -> bool { return !fileSetArg.GetType().empty(); }) ||
+ !cxxModuleBmiArgs.GetType().empty()) {
status.SetError(
"TARGETS given TYPE option. The TYPE option may only be specified in "
" install(FILES) and install(DIRECTORIES).");
@@ -597,7 +622,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
cmInstallRuntimeDependencySet* runtimeDependencySet = nullptr;
- if (withRuntimeDependencies) {
+ if (runtimeDependenciesArgVector) {
if (!runtimeDependencySetArg.empty()) {
status.SetError("TARGETS cannot have both RUNTIME_DEPENDENCIES and "
"RUNTIME_DEPENDENCY_SET.");
@@ -706,6 +731,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
bool installsPublicHeader = false;
bool installsResource = false;
std::vector<bool> installsFileSet(fileSetArgs.size(), false);
+ bool installsCxxModuleBmi = false;
// Generate install script code to install the given targets.
for (cmTarget* ti : targets) {
@@ -722,6 +748,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
std::unique_ptr<cmInstallFilesGenerator> publicHeaderGenerator;
std::unique_ptr<cmInstallFilesGenerator> resourceGenerator;
std::vector<std::unique_ptr<cmInstallFileSetGenerator>> fileSetGenerators;
+ std::unique_ptr<cmInstallCxxModuleBmiGenerator> cxxModuleBmiGenerator;
// Avoid selecting default destinations for PUBLIC_HEADER and
// PRIVATE_HEADER if any artifacts are specified.
@@ -760,6 +787,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
for (auto const& gen : fileSetGenerators) {
te->FileSetGenerators[gen->GetFileSet()] = gen.get();
}
+ te->CxxModuleBmiGenerator = cxxModuleBmiGenerator.get();
target.AddInstallIncludeDirectories(
*te, cmMakeRange(includesArgs.GetIncludeDirs()));
te->NamelinkOnly = namelinkOnly;
@@ -1105,6 +1133,19 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
}
}
+ if (supportCxx20FileSetTypes &&
+ !cxxModuleBmiArgs.GetDestination().empty()) {
+ cxxModuleBmiGenerator = cm::make_unique<cmInstallCxxModuleBmiGenerator>(
+ target.GetName(),
+ helper.GetCxxModulesBmiDestination(&cxxModuleBmiArgs),
+ cxxModuleBmiArgs.GetPermissions(),
+ cxxModuleBmiArgs.GetConfigurations(), cxxModuleBmiArgs.GetComponent(),
+ cmInstallGenerator::SelectMessageLevel(target.GetMakefile()),
+ cxxModuleBmiArgs.GetExcludeFromAll(), cxxModuleBmiArgs.GetOptional(),
+ helper.Makefile->GetBacktrace());
+ target.SetHaveInstallRule(true);
+ }
+
// Add this install rule to an export if one was specified.
if (!addTargetExport()) {
return false;
@@ -1121,6 +1162,7 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
installsPrivateHeader = installsPrivateHeader || privateHeaderGenerator;
installsPublicHeader = installsPublicHeader || publicHeaderGenerator;
installsResource = installsResource || resourceGenerator;
+ installsCxxModuleBmi = installsCxxModuleBmi || cxxModuleBmiGenerator;
helper.Makefile->AddInstallGenerator(std::move(archiveGenerator));
helper.Makefile->AddInstallGenerator(std::move(libraryGenerator));
@@ -1135,9 +1177,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
for (auto& gen : fileSetGenerators) {
helper.Makefile->AddInstallGenerator(std::move(gen));
}
+ helper.Makefile->AddInstallGenerator(std::move(cxxModuleBmiGenerator));
}
- if (withRuntimeDependencies && !runtimeDependencySet->Empty()) {
+ if (runtimeDependenciesArgVector && !runtimeDependencySet->Empty()) {
AddInstallRuntimeDependenciesGenerator(
helper, runtimeDependencySet, runtimeArgs, libraryArgs, frameworkArgs,
std::move(runtimeDependenciesArgs), installsRuntime, installsLibrary,
@@ -1192,6 +1235,10 @@ bool HandleTargetsMode(std::vector<std::string> const& args,
fileSetArgs[i].GetComponent());
}
}
+ if (installsCxxModuleBmi) {
+ helper.Makefile->GetGlobalGenerator()->AddInstallComponent(
+ cxxModuleBmiArgs.GetComponent());
+ }
return true;
}
@@ -1206,10 +1253,10 @@ bool HandleImportedRuntimeArtifactsMode(std::vector<std::string> const& args,
struct ArgVectors
{
- std::vector<std::string> Library;
- std::vector<std::string> Runtime;
- std::vector<std::string> Framework;
- std::vector<std::string> Bundle;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Library;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Runtime;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Framework;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Bundle;
};
static auto const argHelper = cmArgumentParser<ArgVectors>{}
@@ -1223,7 +1270,7 @@ bool HandleImportedRuntimeArtifactsMode(std::vector<std::string> const& args,
// now parse the generic args (i.e. the ones not specialized on LIBRARY,
// RUNTIME etc. (see above)
- std::vector<std::string> targetList;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> targetList;
std::string runtimeDependencySetArg;
std::vector<std::string> unknownArgs;
cmInstallCommandArguments genericArgs(helper.DefaultComponentName);
@@ -1464,7 +1511,7 @@ bool HandleFilesMode(std::vector<std::string> const& args,
// This is the FILES mode.
bool programs = (args[0] == "PROGRAMS");
cmInstallCommandArguments ica(helper.DefaultComponentName);
- std::vector<std::string> files;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> files;
ica.Bind(programs ? "PROGRAMS"_s : "FILES"_s, files);
std::vector<std::string> unknownArgs;
ica.Parse(args, &unknownArgs);
@@ -1950,7 +1997,7 @@ bool HandleExportAndroidMKMode(std::vector<std::string> const& args,
cm::make_unique<cmInstallExportGenerator>(
&exportSet, ica.GetDestination(), ica.GetPermissions(),
ica.GetConfigurations(), ica.GetComponent(), message,
- ica.GetExcludeFromAll(), fname, name_space, exportOld, true,
+ ica.GetExcludeFromAll(), fname, name_space, "", exportOld, true,
helper.Makefile->GetBacktrace()));
return true;
@@ -1973,12 +2020,19 @@ bool HandleExportMode(std::vector<std::string> const& args,
std::string name_space;
bool exportOld = false;
std::string filename;
+ std::string cxx_modules_directory;
ica.Bind("EXPORT"_s, exp);
ica.Bind("NAMESPACE"_s, name_space);
ica.Bind("EXPORT_LINK_INTERFACE_LIBRARIES"_s, exportOld);
ica.Bind("FILE"_s, filename);
+ bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
+ *helper.Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
+ if (supportCxx20FileSetTypes) {
+ ica.Bind("CXX_MODULES_DIRECTORY"_s, cxx_modules_directory);
+ }
+
std::vector<std::string> unknownArgs;
ica.Parse(args, &unknownArgs);
@@ -2064,8 +2118,8 @@ bool HandleExportMode(std::vector<std::string> const& args,
cm::make_unique<cmInstallExportGenerator>(
&exportSet, ica.GetDestination(), ica.GetPermissions(),
ica.GetConfigurations(), ica.GetComponent(), message,
- ica.GetExcludeFromAll(), fname, name_space, exportOld, false,
- helper.Makefile->GetBacktrace()));
+ ica.GetExcludeFromAll(), fname, name_space, cxx_modules_directory,
+ exportOld, false, helper.Makefile->GetBacktrace()));
return true;
}
@@ -2088,9 +2142,9 @@ bool HandleRuntimeDependencySetMode(std::vector<std::string> const& args,
struct ArgVectors
{
- std::vector<std::string> Library;
- std::vector<std::string> Runtime;
- std::vector<std::string> Framework;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Library;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Runtime;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Framework;
};
static auto const argHelper = cmArgumentParser<ArgVectors>{}
@@ -2106,11 +2160,9 @@ bool HandleRuntimeDependencySetMode(std::vector<std::string> const& args,
// These generic args also contain the runtime dependency set
std::string runtimeDependencySetArg;
std::vector<std::string> runtimeDependencyArgVector;
- std::vector<std::string> parsedArgs;
cmInstallCommandArguments genericArgs(helper.DefaultComponentName);
genericArgs.Bind("RUNTIME_DEPENDENCY_SET"_s, runtimeDependencySetArg);
- genericArgs.Parse(genericArgVector, &runtimeDependencyArgVector, nullptr,
- &parsedArgs);
+ genericArgs.Parse(genericArgVector, &runtimeDependencyArgVector);
bool success = genericArgs.Finalize();
cmInstallCommandArguments libraryArgs(helper.DefaultComponentName);
@@ -2280,6 +2332,15 @@ std::string Helper::GetLibraryDestination(
return this->GetDestination(args, "CMAKE_INSTALL_LIBDIR", "lib");
}
+std::string Helper::GetCxxModulesBmiDestination(
+ const cmInstallCommandArguments* args) const
+{
+ if (args) {
+ return args->GetDestination();
+ }
+ return {};
+}
+
std::string Helper::GetIncludeDestination(
const cmInstallCommandArguments* args) const
{
diff --git a/Source/cmInstallCommandArguments.h b/Source/cmInstallCommandArguments.h
index 79bd945..6e46aac 100644
--- a/Source/cmInstallCommandArguments.h
+++ b/Source/cmInstallCommandArguments.h
@@ -8,6 +8,7 @@
#include <vector>
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
class cmInstallCommandArguments : public cmArgumentParser<void>
{
@@ -44,8 +45,8 @@ private:
std::string NamelinkComponent;
bool ExcludeFromAll = false;
std::string Rename;
- std::vector<std::string> Permissions;
- std::vector<std::string> Configurations;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Permissions;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Configurations;
bool Optional = false;
bool NamelinkOnly = false;
bool NamelinkSkip = false;
diff --git a/Source/cmInstallCxxModuleBmiGenerator.cxx b/Source/cmInstallCxxModuleBmiGenerator.cxx
new file mode 100644
index 0000000..1ef1eaa
--- /dev/null
+++ b/Source/cmInstallCxxModuleBmiGenerator.cxx
@@ -0,0 +1,75 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmInstallCxxModuleBmiGenerator.h"
+
+#include <ostream>
+#include <utility>
+
+#include "cmGeneratorExpression.h"
+#include "cmGeneratorTarget.h"
+#include "cmGlobalGenerator.h"
+#include "cmListFileCache.h"
+#include "cmLocalGenerator.h"
+#include "cmOutputConverter.h"
+#include "cmStringAlgorithms.h"
+
+cmInstallCxxModuleBmiGenerator::cmInstallCxxModuleBmiGenerator(
+ std::string target, std::string const& dest, std::string file_permissions,
+ std::vector<std::string> const& configurations, std::string const& component,
+ MessageLevel message, bool exclude_from_all, bool optional,
+ cmListFileBacktrace backtrace)
+ : cmInstallGenerator(dest, configurations, component, message,
+ exclude_from_all, false, std::move(backtrace))
+ , TargetName(std::move(target))
+ , FilePermissions(std::move(file_permissions))
+ , Optional(optional)
+{
+ this->ActionsPerConfig = true;
+}
+
+cmInstallCxxModuleBmiGenerator::~cmInstallCxxModuleBmiGenerator() = default;
+
+bool cmInstallCxxModuleBmiGenerator::Compute(cmLocalGenerator* lg)
+{
+ this->LocalGenerator = lg;
+
+ this->Target = lg->FindLocalNonAliasGeneratorTarget(this->TargetName);
+ if (!this->Target) {
+ // If no local target has been found, find it in the global scope.
+ this->Target =
+ lg->GetGlobalGenerator()->FindGeneratorTarget(this->TargetName);
+ }
+
+ return true;
+}
+
+std::string cmInstallCxxModuleBmiGenerator::GetScriptLocation(
+ std::string const& config) const
+{
+ char const* config_name = config.c_str();
+ if (config.empty()) {
+ config_name = "noconfig";
+ }
+ return cmStrCat(this->Target->GetSupportDirectory(),
+ "/install-cxx-module-bmi-", config_name, ".cmake");
+}
+
+std::string cmInstallCxxModuleBmiGenerator::GetDestination(
+ std::string const& config) const
+{
+ return cmGeneratorExpression::Evaluate(this->Destination,
+ this->LocalGenerator, config);
+}
+
+void cmInstallCxxModuleBmiGenerator::GenerateScriptForConfig(
+ std::ostream& os, const std::string& config, Indent indent)
+{
+ auto const& loc = this->GetScriptLocation(config);
+ if (loc.empty()) {
+ return;
+ }
+ os << indent << "include(\""
+ << cmOutputConverter::EscapeForCMake(
+ loc, cmOutputConverter::WrapQuotes::NoWrap)
+ << "\" OPTIONAL)\n";
+}
diff --git a/Source/cmInstallCxxModuleBmiGenerator.h b/Source/cmInstallCxxModuleBmiGenerator.h
new file mode 100644
index 0000000..21edb2e
--- /dev/null
+++ b/Source/cmInstallCxxModuleBmiGenerator.h
@@ -0,0 +1,52 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#pragma once
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+
+#include "cmInstallGenerator.h"
+#include "cmScriptGenerator.h"
+
+class cmGeneratorTarget;
+class cmListFileBacktrace;
+class cmLocalGenerator;
+
+/** \class cmInstallCxxModuleBmiGenerator
+ * \brief Generate C++ module BMI installation rules.
+ */
+class cmInstallCxxModuleBmiGenerator : public cmInstallGenerator
+{
+public:
+ cmInstallCxxModuleBmiGenerator(
+ std::string target, std::string const& dest, std::string file_permissions,
+ std::vector<std::string> const& configurations,
+ std::string const& component, MessageLevel message, bool exclude_from_all,
+ bool optional, cmListFileBacktrace backtrace);
+ ~cmInstallCxxModuleBmiGenerator() override;
+
+ bool Compute(cmLocalGenerator* lg) override;
+
+ std::string const& GetFilePermissions() const
+ {
+ return this->FilePermissions;
+ }
+ std::string GetDestination(std::string const& config) const;
+ std::string GetScriptLocation(std::string const& config) const;
+ cmGeneratorTarget const* GetTarget() const { return this->Target; }
+ bool GetOptional() const { return this->Optional; }
+ MessageLevel GetMessageLevel() const { return this->Message; }
+
+protected:
+ void GenerateScriptForConfig(std::ostream& os, const std::string& config,
+ Indent indent) override;
+
+ std::string const TargetName;
+ cmGeneratorTarget const* Target = nullptr;
+ cmLocalGenerator* LocalGenerator = nullptr;
+ std::string const FilePermissions;
+ bool const Optional;
+};
diff --git a/Source/cmInstallExportGenerator.cxx b/Source/cmInstallExportGenerator.cxx
index b80437d..1d81b0b 100644
--- a/Source/cmInstallExportGenerator.cxx
+++ b/Source/cmInstallExportGenerator.cxx
@@ -23,7 +23,8 @@ cmInstallExportGenerator::cmInstallExportGenerator(
cmExportSet* exportSet, std::string const& destination,
std::string file_permissions, std::vector<std::string> const& configurations,
std::string const& component, MessageLevel message, bool exclude_from_all,
- std::string filename, std::string name_space, bool exportOld, bool android,
+ std::string filename, std::string name_space,
+ std::string cxx_modules_directory, bool exportOld, bool android,
cmListFileBacktrace backtrace)
: cmInstallGenerator(destination, configurations, component, message,
exclude_from_all, false, std::move(backtrace))
@@ -31,6 +32,7 @@ cmInstallExportGenerator::cmInstallExportGenerator(
, FilePermissions(std::move(file_permissions))
, FileName(std::move(filename))
, Namespace(std::move(name_space))
+ , CxxModulesDirectory(std::move(cxx_modules_directory))
, ExportOld(exportOld)
{
if (android) {
@@ -141,6 +143,75 @@ void cmInstallExportGenerator::GenerateScriptConfigs(std::ostream& os,
os << indent << "endif()\n";
files.clear();
}
+
+ // Now create a configuration-specific install rule for the C++ module import
+ // property file of each configuration.
+ auto cxx_module_dest =
+ cmStrCat(this->Destination, '/', this->CxxModulesDirectory);
+ std::string config_file_example;
+ for (auto const& i : this->EFGen->GetConfigCxxModuleFiles()) {
+ config_file_example = i.second;
+ break;
+ }
+ if (!config_file_example.empty()) {
+ // Remove old per-configuration export files if the main changes.
+ std::string installedDir = cmStrCat(
+ "$ENV{DESTDIR}", ConvertToAbsoluteDestination(cxx_module_dest), '/');
+ std::string installedFile = cmStrCat(installedDir, "/cxx-modules.cmake");
+ std::string toInstallFile =
+ cmStrCat(cmSystemTools::GetFilenamePath(config_file_example),
+ "/cxx-modules.cmake");
+ os << indent << "if(EXISTS \"" << installedFile << "\")\n";
+ Indent indentN = indent.Next();
+ Indent indentNN = indentN.Next();
+ Indent indentNNN = indentNN.Next();
+ /* clang-format off */
+ os << indentN << "file(DIFFERENT _cmake_export_file_changed FILES\n"
+ << indentN << " \"" << installedFile << "\"\n"
+ << indentN << " \"" << toInstallFile << "\")\n";
+ os << indentN << "if(_cmake_export_file_changed)\n";
+ os << indentNN << "file(GLOB _cmake_old_config_files \"" << installedDir
+ << this->EFGen->GetConfigImportFileGlob() << "\")\n";
+ os << indentNN << "if(_cmake_old_config_files)\n";
+ os << indentNNN << "string(REPLACE \";\" \", \" _cmake_old_config_files_text \"${_cmake_old_config_files}\")\n";
+ os << indentNNN << R"(message(STATUS "Old C++ module export file \")" << installedFile
+ << "\\\" will be replaced. Removing files [${_cmake_old_config_files_text}].\")\n";
+ os << indentNNN << "unset(_cmake_old_config_files_text)\n";
+ os << indentNNN << "file(REMOVE ${_cmake_old_config_files})\n";
+ os << indentNN << "endif()\n";
+ os << indentNN << "unset(_cmake_old_config_files)\n";
+ os << indentN << "endif()\n";
+ os << indentN << "unset(_cmake_export_file_changed)\n";
+ os << indent << "endif()\n";
+ /* clang-format on */
+
+ // All of these files are siblings; get its location to know where the
+ // "anchor" file is.
+ files.push_back(toInstallFile);
+ this->AddInstallRule(os, cxx_module_dest, cmInstallType_FILES, files,
+ false, this->FilePermissions.c_str(), nullptr,
+ nullptr, nullptr, indent);
+ files.clear();
+ }
+ for (auto const& i : this->EFGen->GetConfigCxxModuleFiles()) {
+ files.push_back(i.second);
+ std::string config_test = this->CreateConfigTest(i.first);
+ os << indent << "if(" << config_test << ")\n";
+ this->AddInstallRule(os, cxx_module_dest, cmInstallType_FILES, files,
+ false, this->FilePermissions.c_str(), nullptr,
+ nullptr, nullptr, indent.Next());
+ os << indent << "endif()\n";
+ files.clear();
+ }
+ for (auto const& i : this->EFGen->GetConfigCxxModuleTargetFiles()) {
+ std::string config_test = this->CreateConfigTest(i.first);
+ os << indent << "if(" << config_test << ")\n";
+ this->AddInstallRule(os, cxx_module_dest, cmInstallType_FILES, i.second,
+ false, this->FilePermissions.c_str(), nullptr,
+ nullptr, nullptr, indent.Next());
+ os << indent << "endif()\n";
+ files.clear();
+ }
}
void cmInstallExportGenerator::GenerateScriptActions(std::ostream& os,
diff --git a/Source/cmInstallExportGenerator.h b/Source/cmInstallExportGenerator.h
index 02fe1fa..346ca67 100644
--- a/Source/cmInstallExportGenerator.h
+++ b/Source/cmInstallExportGenerator.h
@@ -28,7 +28,8 @@ public:
const std::vector<std::string>& configurations,
std::string const& component, MessageLevel message,
bool exclude_from_all, std::string filename,
- std::string name_space, bool exportOld,
+ std::string name_space,
+ std::string cxx_modules_directory, bool exportOld,
bool android, cmListFileBacktrace backtrace);
cmInstallExportGenerator(const cmInstallExportGenerator&) = delete;
~cmInstallExportGenerator() override;
@@ -50,6 +51,10 @@ public:
std::string GetDestinationFile() const;
std::string GetFileName() const { return this->FileName; }
std::string GetTempDir() const;
+ std::string GetCxxModuleDirectory() const
+ {
+ return this->CxxModulesDirectory;
+ }
protected:
void GenerateScript(std::ostream& os) override;
@@ -64,6 +69,7 @@ protected:
std::string const FilePermissions;
std::string const FileName;
std::string const Namespace;
+ std::string const CxxModulesDirectory;
bool const ExportOld;
cmLocalGenerator* LocalGenerator = nullptr;
diff --git a/Source/cmLinkLineDeviceComputer.cxx b/Source/cmLinkLineDeviceComputer.cxx
index 43f1b8e..b06dc3d 100644
--- a/Source/cmLinkLineDeviceComputer.cxx
+++ b/Source/cmLinkLineDeviceComputer.cxx
@@ -57,7 +57,6 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
// For this we only consider targets
using ItemVector = cmComputeLinkInformation::ItemVector;
ItemVector const& items = cli.GetItems();
- std::string config = cli.GetConfig();
return std::any_of(
items.begin(), items.end(),
[](cmComputeLinkInformation::Item const& item) -> bool {
@@ -69,6 +68,26 @@ bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinking(
});
}
+bool cmLinkLineDeviceComputer::ComputeRequiresDeviceLinkingIPOFlag(
+ cmComputeLinkInformation& cli)
+{
+ // Determine if this item might requires device linking.
+ // For this we only consider targets
+ using ItemVector = cmComputeLinkInformation::ItemVector;
+ ItemVector const& items = cli.GetItems();
+ std::string config = cli.GetConfig();
+ return std::any_of(
+ items.begin(), items.end(),
+ [config](cmComputeLinkInformation::Item const& item) -> bool {
+ return item.Target &&
+ item.Target->GetType() == cmStateEnums::STATIC_LIBRARY &&
+ // this dependency requires us to device link it
+ !item.Target->GetPropertyAsBool("CUDA_RESOLVE_DEVICE_SYMBOLS") &&
+ item.Target->GetPropertyAsBool("CUDA_SEPARABLE_COMPILATION") &&
+ item.Target->IsIPOEnabled("CUDA", config);
+ });
+}
+
void cmLinkLineDeviceComputer::ComputeLinkLibraries(
cmComputeLinkInformation& cli, std::string const& stdLibString,
std::vector<BT<std::string>>& linkLibraries)
diff --git a/Source/cmLinkLineDeviceComputer.h b/Source/cmLinkLineDeviceComputer.h
index dee625b..0916307 100644
--- a/Source/cmLinkLineDeviceComputer.h
+++ b/Source/cmLinkLineDeviceComputer.h
@@ -30,6 +30,7 @@ public:
delete;
bool ComputeRequiresDeviceLinking(cmComputeLinkInformation& cli);
+ bool ComputeRequiresDeviceLinkingIPOFlag(cmComputeLinkInformation& cli);
void ComputeLinkLibraries(
cmComputeLinkInformation& cli, std::string const& stdLibString,
diff --git a/Source/cmListFileCache.cxx b/Source/cmListFileCache.cxx
index 91157cb..6270c82 100644
--- a/Source/cmListFileCache.cxx
+++ b/Source/cmListFileCache.cxx
@@ -347,6 +347,7 @@ enum class NestingStateEnum
Foreach,
Function,
Macro,
+ Block
};
struct NestingState
@@ -434,6 +435,16 @@ cm::optional<cmListFileContext> cmListFileParser::CheckNesting() const
return cmListFileContext::FromListFileFunction(func, this->FileName);
}
stack.pop_back();
+ } else if (name == "block") {
+ stack.push_back({
+ NestingStateEnum::Block,
+ cmListFileContext::FromListFileFunction(func, this->FileName),
+ });
+ } else if (name == "endblock") {
+ if (!TopIs(stack, NestingStateEnum::Block)) {
+ return cmListFileContext::FromListFileFunction(func, this->FileName);
+ }
+ stack.pop_back();
}
}
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index 67c8bf2..b44d2a0 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -15,6 +15,7 @@
#include <vector>
#include <cm/memory>
+#include <cm/optional>
#include <cm/string_view>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -36,6 +37,7 @@
#include "cmInstallScriptGenerator.h"
#include "cmInstallTargetGenerator.h"
#include "cmLinkLineComputer.h"
+#include "cmLinkLineDeviceComputer.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
@@ -1381,7 +1383,7 @@ std::vector<BT<std::string>> cmLocalGenerator::GetStaticLibraryFlags(
}
void cmLocalGenerator::GetDeviceLinkFlags(
- cmLinkLineComputer& linkLineComputer, const std::string& config,
+ cmLinkLineDeviceComputer& linkLineComputer, const std::string& config,
std::string& linkLibs, std::string& linkFlags, std::string& frameworkPath,
std::string& linkPath, cmGeneratorTarget* target)
{
@@ -1389,6 +1391,18 @@ void cmLocalGenerator::GetDeviceLinkFlags(
cmComputeLinkInformation* pcli = target->GetLinkInformation(config);
+ auto linklang = linkLineComputer.GetLinkerLanguage(target, config);
+ auto ipoEnabled = target->IsIPOEnabled(linklang, config);
+ if (!ipoEnabled) {
+ ipoEnabled = linkLineComputer.ComputeRequiresDeviceLinkingIPOFlag(*pcli);
+ }
+ if (ipoEnabled) {
+ if (cmValue cudaIPOFlags = this->Makefile->GetDefinition(
+ "CMAKE_CUDA_DEVICE_LINK_OPTIONS_IPO")) {
+ linkFlags += cudaIPOFlags;
+ }
+ }
+
if (pcli) {
// Compute the required device link libraries when
// resolving gpu lang device symbols
@@ -1396,6 +1410,8 @@ void cmLocalGenerator::GetDeviceLinkFlags(
linkPath);
}
+ // iterate link deps and see if any of them need IPO
+
std::vector<std::string> linkOpts;
target->GetLinkOptions(linkOpts, config, "CUDA");
// LINK_OPTIONS are escaped.
@@ -1590,7 +1606,8 @@ std::vector<BT<std::string>> cmLocalGenerator::GetTargetCompileFlags(
cmMakefile* mf = this->GetMakefile();
// Add language-specific flags.
- this->AddLanguageFlags(compileFlags, target, lang, config);
+ this->AddLanguageFlags(compileFlags, target, cmBuildStep::Compile, lang,
+ config);
if (target->IsIPOEnabled(lang, config)) {
this->AppendFeatureOptions(compileFlags, lang, "IPO");
@@ -1903,6 +1920,7 @@ void cmLocalGenerator::AddArchitectureFlags(std::string& flags,
void cmLocalGenerator::AddLanguageFlags(std::string& flags,
cmGeneratorTarget const* target,
+ cmBuildStep compileOrLink,
const std::string& lang,
const std::string& config)
{
@@ -1926,7 +1944,7 @@ void cmLocalGenerator::AddLanguageFlags(std::string& flags,
}
}
} else if (lang == "CUDA") {
- target->AddCUDAArchitectureFlags(flags);
+ target->AddCUDAArchitectureFlags(compileOrLink, config, flags);
target->AddCUDAToolkitFlags(flags);
} else if (lang == "ISPC") {
target->AddISPCTargetFlags(flags);
@@ -2038,7 +2056,7 @@ void cmLocalGenerator::AddLanguageFlagsForLinking(
this->AddCompilerRequirementFlag(flags, target, lang, config);
}
- this->AddLanguageFlags(flags, target, lang, config);
+ this->AddLanguageFlags(flags, target, cmBuildStep::Link, lang, config);
if (target->IsIPOEnabled(lang, config)) {
this->AppendFeatureOptions(flags, lang, "IPO");
@@ -2574,7 +2592,9 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
if (pchSource.empty() || pchHeader.empty()) {
if (this->GetGlobalGenerator()->IsXcode() && !pchLangSet.empty()) {
for (auto* sf : sources) {
- if (pchLangSet.find(sf->GetLanguage()) == pchLangSet.end()) {
+ const auto sourceLanguage = sf->GetLanguage();
+ if (!sourceLanguage.empty() &&
+ pchLangSet.find(sourceLanguage) == pchLangSet.end()) {
sf->SetProperty("SKIP_PRECOMPILE_HEADERS", "ON");
}
}
@@ -2667,7 +2687,7 @@ void cmLocalGenerator::AddPchDependencies(cmGeneratorTarget* target)
cmStrCat(linkerProperty, configUpper),
cmStrCat(" ",
this->ConvertToOutputFormat(pchSourceObj, SHELL)),
- true);
+ cm::nullopt, true);
} else if (reuseTarget->GetType() ==
cmStateEnums::OBJECT_LIBRARY) {
// FIXME: This can propagate more than one level, unlike
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 7cae1fc..0529431 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -35,6 +35,7 @@ class cmGeneratorTarget;
class cmGlobalGenerator;
class cmImplicitDependsList;
class cmLinkLineComputer;
+class cmLinkLineDeviceComputer;
class cmMakefile;
class cmRulePlaceholderExpander;
class cmSourceFile;
@@ -59,6 +60,13 @@ enum class cmDependencyScannerKind
Compiler
};
+/** What to compute language flags for */
+enum class cmBuildStep
+{
+ Compile,
+ Link
+};
+
/** Target and source file which have a specific output. */
struct cmSourcesWithOutput
{
@@ -143,7 +151,8 @@ public:
const std::string& filterArch = std::string());
void AddLanguageFlags(std::string& flags, cmGeneratorTarget const* target,
- const std::string& lang, const std::string& config);
+ cmBuildStep compileOrLink, const std::string& lang,
+ const std::string& config);
void AddLanguageFlagsForLinking(std::string& flags,
cmGeneratorTarget const* target,
const std::string& lang,
@@ -476,7 +485,7 @@ public:
/** Fill out these strings for the given target. Libraries to link,
* flags, and linkflags. */
- void GetDeviceLinkFlags(cmLinkLineComputer& linkLineComputer,
+ void GetDeviceLinkFlags(cmLinkLineDeviceComputer& linkLineComputer,
const std::string& config, std::string& linkLibs,
std::string& linkFlags, std::string& frameworkPath,
std::string& linkPath, cmGeneratorTarget* target);
diff --git a/Source/cmLocalUnixMakefileGenerator3.cxx b/Source/cmLocalUnixMakefileGenerator3.cxx
index e125470..de1d3cd 100644
--- a/Source/cmLocalUnixMakefileGenerator3.cxx
+++ b/Source/cmLocalUnixMakefileGenerator3.cxx
@@ -1412,13 +1412,16 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
if (needRescanDependInfo || needRescanDirInfo || needRescanDependencies) {
// The dependencies must be regenerated.
- std::string targetName = cmSystemTools::GetFilenameName(targetDir);
- targetName = targetName.substr(0, targetName.length() - 4);
- std::string message =
- cmStrCat("Scanning dependencies of target ", targetName);
- cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
- cmsysTerminal_Color_ForegroundBold,
- message.c_str(), true, color);
+ if (verbose) {
+ std::string targetName = cmSystemTools::GetFilenameName(targetDir);
+ targetName = targetName.substr(0, targetName.length() - 4);
+ std::string message =
+ cmStrCat("Scanning dependencies of target ", targetName);
+ cmSystemTools::MakefileColorEcho(
+ cmsysTerminal_Color_ForegroundMagenta |
+ cmsysTerminal_Color_ForegroundBold,
+ message.c_str(), true, color);
+ }
status = this->ScanDependencies(targetDir, dependFile,
internalDependFile, validDependencies);
@@ -1447,13 +1450,19 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
this->GetBinaryDirectory())
: std::function<bool(const std::string&)>())) {
// regenerate dependencies files
- std::string targetName =
- cmCMakePath(targetDir).GetFileName().RemoveExtension().GenericString();
- auto message = cmStrCat(
- "Consolidate compiler generated dependencies of target ", targetName);
- cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundMagenta |
- cmsysTerminal_Color_ForegroundBold,
- message.c_str(), true, color);
+ if (verbose) {
+ std::string targetName = cmCMakePath(targetDir)
+ .GetFileName()
+ .RemoveExtension()
+ .GenericString();
+ auto message =
+ cmStrCat("Consolidate compiler generated dependencies of target ",
+ targetName);
+ cmSystemTools::MakefileColorEcho(
+ cmsysTerminal_Color_ForegroundMagenta |
+ cmsysTerminal_Color_ForegroundBold,
+ message.c_str(), true, color);
+ }
// Open the make depends file. This should be copy-if-different
// because the make tool may try to reload it needlessly otherwise.
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index f65add1..0451d96 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -680,7 +680,8 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
langForClCompile = linkLanguage;
if (langForClCompile == "C" || langForClCompile == "CXX" ||
langForClCompile == "Fortran") {
- this->AddLanguageFlags(flags, target, langForClCompile, configName);
+ this->AddLanguageFlags(flags, target, cmBuildStep::Compile,
+ langForClCompile, configName);
}
// set the correct language
if (linkLanguage == "C") {
diff --git a/Source/cmMacroCommand.cxx b/Source/cmMacroCommand.cxx
index ef12487..47ad749 100644
--- a/Source/cmMacroCommand.cxx
+++ b/Source/cmMacroCommand.cxx
@@ -126,7 +126,7 @@ bool cmMacroHelperCommand::operator()(
return false;
}
if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
+ inStatus.SetReturnInvoked(status.GetReturnVariables());
return true;
}
if (status.GetBreakInvoked()) {
diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx
index 469eac3..cf5d880 100644
--- a/Source/cmMakefile.cxx
+++ b/Source/cmMakefile.cxx
@@ -149,6 +149,29 @@ void cmMakefile::IssueMessage(MessageType t, std::string const& text) const
this->GetCMakeInstance()->IssueMessage(t, text, this->Backtrace);
}
+Message::LogLevel cmMakefile::GetCurrentLogLevel() const
+{
+ const cmake* cmakeInstance = this->GetCMakeInstance();
+
+ const Message::LogLevel logLevelCliOrDefault = cmakeInstance->GetLogLevel();
+ assert("Expected a valid log level here" &&
+ logLevelCliOrDefault != Message::LogLevel::LOG_UNDEFINED);
+
+ Message::LogLevel result = logLevelCliOrDefault;
+
+ // If the log-level was set via the command line option, it takes precedence
+ // over the CMAKE_MESSAGE_LOG_LEVEL variable.
+ if (!cmakeInstance->WasLogLevelSetViaCLI()) {
+ const Message::LogLevel logLevelFromVar = cmake::StringToLogLevel(
+ this->GetSafeDefinition("CMAKE_MESSAGE_LOG_LEVEL"));
+ if (logLevelFromVar != Message::LogLevel::LOG_UNDEFINED) {
+ result = logLevelFromVar;
+ }
+ }
+
+ return result;
+}
+
bool cmMakefile::CheckCMP0037(std::string const& targetName,
cmStateEnums::TargetType targetType) const
{
@@ -766,6 +789,7 @@ void cmMakefile::RunListFile(cmListFile const& listFile,
break;
}
if (status.GetReturnInvoked()) {
+ this->RaiseScope(status.GetReturnVariables());
// Exit early due to return command.
break;
}
@@ -3456,7 +3480,7 @@ void cmMakefile::AddTargetObject(std::string const& tgtName,
#endif
}
-void cmMakefile::EnableLanguage(std::vector<std::string> const& lang,
+void cmMakefile::EnableLanguage(std::vector<std::string> const& languages,
bool optional)
{
if (this->DeferRunning) {
@@ -3468,24 +3492,48 @@ void cmMakefile::EnableLanguage(std::vector<std::string> const& lang,
if (const char* def = this->GetGlobalGenerator()->GetCMakeCFGIntDir()) {
this->AddDefinition("CMAKE_CFG_INTDIR", def);
}
+
+ std::vector<std::string> unique_languages;
+ {
+ std::vector<std::string> duplicate_languages;
+ for (std::string const& language : languages) {
+ if (!cm::contains(unique_languages, language)) {
+ unique_languages.push_back(language);
+ } else if (!cm::contains(duplicate_languages, language)) {
+ duplicate_languages.push_back(language);
+ }
+ }
+ if (!duplicate_languages.empty()) {
+ auto quantity = duplicate_languages.size() == 1 ? std::string(" has")
+ : std::string("s have");
+ this->IssueMessage(MessageType::AUTHOR_WARNING,
+ "Languages to be enabled may not be specified more "
+ "than once at the same time. The following language" +
+ quantity + " been specified multiple times: " +
+ cmJoin(duplicate_languages, ", "));
+ }
+ }
+
// If RC is explicitly listed we need to do it after other languages.
// On some platforms we enable RC implicitly while enabling others.
// Do not let that look like recursive enable_language(RC).
- std::vector<std::string> langs;
- std::vector<std::string> langsRC;
- langs.reserve(lang.size());
- for (std::string const& i : lang) {
- if (i == "RC") {
- langsRC.push_back(i);
+ std::vector<std::string> languages_without_RC;
+ std::vector<std::string> languages_for_RC;
+ languages_without_RC.reserve(unique_languages.size());
+ for (std::string const& language : unique_languages) {
+ if (language == "RC") {
+ languages_for_RC.push_back(language);
} else {
- langs.push_back(i);
+ languages_without_RC.push_back(language);
}
}
- if (!langs.empty()) {
- this->GetGlobalGenerator()->EnableLanguage(langs, this, optional);
+ if (!languages_without_RC.empty()) {
+ this->GetGlobalGenerator()->EnableLanguage(languages_without_RC, this,
+ optional);
}
- if (!langsRC.empty()) {
- this->GetGlobalGenerator()->EnableLanguage(langsRC, this, optional);
+ if (!languages_for_RC.empty()) {
+ this->GetGlobalGenerator()->EnableLanguage(languages_for_RC, this,
+ optional);
}
}
@@ -4116,6 +4164,18 @@ void cmMakefile::RaiseScope(const std::string& var, const char* varDef)
#endif
}
+void cmMakefile::RaiseScope(const std::vector<std::string>& variables)
+{
+ for (auto const& varName : variables) {
+ if (this->IsNormalDefinitionSet(varName)) {
+ this->RaiseScope(varName, this->GetDefinition(varName));
+ } else {
+ // unset variable in parent scope
+ this->RaiseScope(varName, nullptr);
+ }
+ }
+}
+
cmTarget* cmMakefile::AddImportedTarget(const std::string& name,
cmStateEnums::TargetType type,
bool global)
@@ -4406,7 +4466,7 @@ bool cmMakefile::SetPolicy(cmPolicies::PolicyID id,
}
// Deprecate old policies.
- if (status == cmPolicies::OLD && id <= cmPolicies::CMP0097 &&
+ if (status == cmPolicies::OLD && id <= cmPolicies::CMP0102 &&
!(this->GetCMakeInstance()->GetIsInTryCompile() &&
(
// Policies set by cmCoreTryCompile::TryCompileCode.
@@ -4471,6 +4531,19 @@ bool cmMakefile::SetPolicyVersion(std::string const& version_min,
cmPolicies::WarnCompat::On);
}
+cmMakefile::VariablePushPop::VariablePushPop(cmMakefile* m)
+ : Makefile(m)
+{
+ this->Makefile->StateSnapshot =
+ this->Makefile->GetState()->CreateVariableScopeSnapshot(
+ this->Makefile->StateSnapshot);
+}
+
+cmMakefile::VariablePushPop::~VariablePushPop()
+{
+ this->Makefile->PopSnapshot();
+}
+
bool cmMakefile::HasCMP0054AlreadyBeenReported(
cmListFileContext const& context) const
{
diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h
index 27838b2..873454d 100644
--- a/Source/cmMakefile.h
+++ b/Source/cmMakefile.h
@@ -376,6 +376,20 @@ public:
};
friend class PolicyPushPop;
+ /** Helper class to push and pop variables scopes automatically. */
+ class VariablePushPop
+ {
+ public:
+ VariablePushPop(cmMakefile* m);
+ ~VariablePushPop();
+
+ VariablePushPop(VariablePushPop const&) = delete;
+ VariablePushPop& operator=(VariablePushPop const&) = delete;
+
+ private:
+ cmMakefile* Makefile;
+ };
+
/**
* Determine if the given context, name pair has already been reported
* in context of CMP0054.
@@ -861,6 +875,11 @@ public:
void PushScope();
void PopScope();
void RaiseScope(const std::string& var, const char* value);
+ void RaiseScope(const std::string& var, cmValue value)
+ {
+ this->RaiseScope(var, value.GetCStr());
+ }
+ void RaiseScope(const std::vector<std::string>& variables);
// push and pop loop scopes
void PushLoopBlockBarrier();
@@ -924,6 +943,7 @@ public:
};
void IssueMessage(MessageType t, std::string const& text) const;
+ Message::LogLevel GetCurrentLogLevel() const;
/** Set whether or not to report a CMP0000 violation. */
void SetCheckCMP0000(bool b) { this->CheckCMP0000 = b; }
diff --git a/Source/cmMakefileExecutableTargetGenerator.cxx b/Source/cmMakefileExecutableTargetGenerator.cxx
index 3849c6f..54f03b9 100644
--- a/Source/cmMakefileExecutableTargetGenerator.cxx
+++ b/Source/cmMakefileExecutableTargetGenerator.cxx
@@ -136,17 +136,11 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
std::vector<std::string> depends;
this->AppendLinkDepends(depends, linkLanguage);
- // Build a list of compiler flags and linker flags.
- std::string langFlags;
- std::string linkFlags;
-
// Add language feature flags.
+ std::string langFlags;
this->LocalGenerator->AddLanguageFlagsForLinking(
langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- // Add device-specific linker flags.
- this->GetDeviceLinkFlags(linkFlags, linkLanguage);
-
// Construct a list of files associated with this executable that
// may need to be cleaned.
std::vector<std::string> exeCleanFiles;
@@ -173,23 +167,32 @@ void cmMakefileExecutableTargetGenerator::WriteNvidiaDeviceExecutableRule(
// Set path conversion for link script shells.
this->LocalGenerator->SetLinkScriptShell(useLinkScript);
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineDeviceComputer> linkLineComputer(
new cmLinkLineDeviceComputer(
this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetRelink(relink);
+ // Create set of linking flags.
+ std::string linkFlags;
+ std::string ignored_;
+ this->LocalGenerator->GetDeviceLinkFlags(
+ *linkLineComputer, this->GetConfigName(), ignored_, linkFlags, ignored_,
+ ignored_, this->GeneratorTarget);
+
// Collect up flags to link in needed libraries.
std::string linkLibs;
- this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
- useResponseFileForLibs, depends);
+ this->CreateLinkLibs(
+ linkLineComputer.get(), linkLibs, useResponseFileForLibs, depends,
+ cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
// Construct object file lists that may be needed to expand the
// rule.
std::string buildObjs;
- this->CreateObjectLists(useLinkScript, false, useResponseFileForObjects,
- buildObjs, depends, false);
+ this->CreateObjectLists(
+ useLinkScript, false, useResponseFileForObjects, buildObjs, depends,
+ false, cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
cmRulePlaceholderExpander::RuleVariables vars;
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
diff --git a/Source/cmMakefileLibraryTargetGenerator.cxx b/Source/cmMakefileLibraryTargetGenerator.cxx
index f30ec27..45ef8c8 100644
--- a/Source/cmMakefileLibraryTargetGenerator.cxx
+++ b/Source/cmMakefileLibraryTargetGenerator.cxx
@@ -287,10 +287,6 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
this->LocalGenerator->AddLanguageFlagsForLinking(
langFlags, this->GeneratorTarget, linkLanguage, this->GetConfigName());
- // Create set of linking flags.
- std::string linkFlags;
- this->GetDeviceLinkFlags(linkFlags, linkLanguage);
-
// Clean files associated with this library.
std::set<std::string> libCleanFiles;
libCleanFiles.insert(
@@ -315,22 +311,31 @@ void cmMakefileLibraryTargetGenerator::WriteNvidiaDeviceLibraryRules(
// Collect up flags to link in needed libraries.
std::string linkLibs;
- std::unique_ptr<cmLinkLineComputer> linkLineComputer(
+ std::unique_ptr<cmLinkLineDeviceComputer> linkLineComputer(
new cmLinkLineDeviceComputer(
this->LocalGenerator,
this->LocalGenerator->GetStateSnapshot().GetDirectory()));
linkLineComputer->SetForResponse(useResponseFileForLibs);
linkLineComputer->SetRelink(relink);
- this->CreateLinkLibs(linkLineComputer.get(), linkLibs,
- useResponseFileForLibs, depends);
+ // Create set of linking flags.
+ std::string linkFlags;
+ std::string ignored_;
+ this->LocalGenerator->GetDeviceLinkFlags(
+ *linkLineComputer, this->GetConfigName(), ignored_, linkFlags, ignored_,
+ ignored_, this->GeneratorTarget);
+
+ this->CreateLinkLibs(
+ linkLineComputer.get(), linkLibs, useResponseFileForLibs, depends,
+ cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
// Construct object file lists that may be needed to expand the
// rule.
std::string buildObjs;
- this->CreateObjectLists(useLinkScript, false, // useArchiveRules
- useResponseFileForObjects, buildObjs, depends,
- false);
+ this->CreateObjectLists(
+ useLinkScript, false, // useArchiveRules
+ useResponseFileForObjects, buildObjs, depends, false,
+ cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink);
std::string objectDir = this->GeneratorTarget->GetSupportDirectory();
objectDir = this->LocalGenerator->ConvertToOutputFormat(
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index aec6577..d19bbb9 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -21,6 +21,7 @@
#include "cmComputeLinkInformation.h"
#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
+#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
@@ -46,6 +47,7 @@
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
+#include "cmTarget.h"
#include "cmValue.h"
#include "cmake.h"
@@ -107,7 +109,7 @@ std::unique_ptr<cmMakefileTargetGenerator> cmMakefileTargetGenerator::New(
return result;
}
-std::string cmMakefileTargetGenerator::GetConfigName()
+std::string cmMakefileTargetGenerator::GetConfigName() const
{
auto const& configNames = this->LocalGenerator->GetConfigNames();
assert(configNames.size() == 1);
@@ -190,6 +192,16 @@ void cmMakefileTargetGenerator::CreateRuleFile()
void cmMakefileTargetGenerator::WriteTargetBuildRules()
{
+ this->GeneratorTarget->CheckCxxModuleStatus(this->GetConfigName());
+
+ if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The \"", this->GeneratorTarget->GetName(),
+ "\" target contains C++ module sources which are not supported "
+ "by the generator"));
+ }
+
// -- Write the custom commands for this target
// Evaluates generator expressions and expands prop_value
@@ -302,6 +314,40 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
}
}
+ std::map<std::string, std::string> file_set_map;
+
+ auto const* tgt = this->GeneratorTarget->Target;
+ for (auto const& name : tgt->GetAllFileSetNames()) {
+ auto const* file_set = tgt->GetFileSet(name);
+ if (!file_set) {
+ this->Makefile->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"", name,
+ "\", but it was not found."));
+ continue;
+ }
+
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, this->LocalGenerator, this->GetConfigName(),
+ this->GeneratorTarget);
+
+ std::map<std::string, std::vector<std::string>> files;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files, entry,
+ this->LocalGenerator, this->GetConfigName(),
+ this->GeneratorTarget);
+ }
+
+ for (auto const& it : files) {
+ for (auto const& filename : it.second) {
+ file_set_map[filename] = file_set->GetType();
+ }
+ }
+ }
+
std::vector<cmSourceFile const*> objectSources;
this->GeneratorTarget->GetObjectSources(objectSources,
this->GetConfigName());
@@ -314,6 +360,25 @@ void cmMakefileTargetGenerator::WriteTargetBuildRules()
this->WriteObjectRuleFiles(*sf);
}
}
+
+ for (cmSourceFile const* sf : objectSources) {
+ auto const& path = sf->GetFullPath();
+ auto const it = file_set_map.find(path);
+ if (it != file_set_map.end()) {
+ auto const& file_set_type = it->second;
+ if (file_set_type == "CXX_MODULES"_s ||
+ file_set_type == "CXX_MODULE_HEADER_UNITS"_s) {
+ if (sf->GetLanguage() != "CXX"_s) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Target \"", tgt->GetName(), "\" contains the source\n ", path,
+ "\nin a file set of type \"", file_set_type,
+ R"(" but the source is not classified as a "CXX" source.)"));
+ }
+ }
+ }
+ }
}
void cmMakefileTargetGenerator::WriteCommonCodeRules()
@@ -977,8 +1042,10 @@ void cmMakefileTargetGenerator::WriteObjectRuleFiles(
lang == "OBJCXX")) {
std::string const clauncher_prop = lang + "_COMPILER_LAUNCHER";
cmValue clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
- if (cmNonempty(clauncher)) {
- compilerLauncher = *clauncher;
+ std::string evaluatedClauncher = cmGeneratorExpression::Evaluate(
+ *clauncher, this->LocalGenerator, config);
+ if (!evaluatedClauncher.empty()) {
+ compilerLauncher = evaluatedClauncher;
}
}
@@ -2080,7 +2147,7 @@ bool cmMakefileTargetGenerator::CheckUseResponseFileForLibraries(
}
std::string cmMakefileTargetGenerator::CreateResponseFile(
- const char* name, std::string const& options,
+ const std::string& name, std::string const& options,
std::vector<std::string>& makefile_depends)
{
// FIXME: Find a better way to determine the response file encoding,
@@ -2126,7 +2193,8 @@ cmMakefileTargetGenerator::CreateLinkLineComputer(
void cmMakefileTargetGenerator::CreateLinkLibs(
cmLinkLineComputer* linkLineComputer, std::string& linkLibs,
- bool useResponseFile, std::vector<std::string>& makefile_depends)
+ bool useResponseFile, std::vector<std::string>& makefile_depends,
+ ResponseFlagFor responseMode)
{
std::string frameworkPath;
std::string linkPath;
@@ -2139,20 +2207,13 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
if (useResponseFile &&
linkLibs.find_first_not_of(' ') != std::string::npos) {
// Lookup the response file reference flag.
- std::string responseFlagVar =
- cmStrCat("CMAKE_",
- this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
- "_RESPONSE_FILE_LINK_FLAG");
- std::string responseFlag;
- if (cmValue p = this->Makefile->GetDefinition(responseFlagVar)) {
- responseFlag = *p;
- } else {
- responseFlag = "@";
- }
+ std::string responseFlag = this->GetResponseFlag(responseMode);
// Create this response file.
+ std::string responseFileName =
+ (responseMode == Link) ? "linkLibs.rsp" : "deviceLinkLibs.rsp";
std::string link_rsp =
- this->CreateResponseFile("linklibs.rsp", linkLibs, makefile_depends);
+ this->CreateResponseFile(responseFileName, linkLibs, makefile_depends);
// Reference the response file.
linkLibs = cmStrCat(responseFlag,
@@ -2164,7 +2225,7 @@ void cmMakefileTargetGenerator::CreateLinkLibs(
void cmMakefileTargetGenerator::CreateObjectLists(
bool useLinkScript, bool useArchiveRules, bool useResponseFile,
std::string& buildObjs, std::vector<std::string>& makefile_depends,
- bool useWatcomQuote)
+ bool useWatcomQuote, ResponseFlagFor responseMode)
{
std::string variableName;
std::string variableNameExternal;
@@ -2179,27 +2240,19 @@ void cmMakefileTargetGenerator::CreateObjectLists(
this->WriteObjectsStrings(object_strings, responseFileLimit);
// Lookup the response file reference flag.
- std::string responseFlagVar =
- cmStrCat("CMAKE_",
- this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName()),
- "_RESPONSE_FILE_LINK_FLAG");
- std::string responseFlag;
- if (cmValue p = this->Makefile->GetDefinition(responseFlagVar)) {
- responseFlag = *p;
- } else {
- responseFlag = "@";
- }
+ std::string responseFlag = this->GetResponseFlag(responseMode);
// Write a response file for each string.
const char* sep = "";
for (unsigned int i = 0; i < object_strings.size(); ++i) {
// Number the response files.
- char rsp[32];
- snprintf(rsp, sizeof(rsp), "objects%u.rsp", i + 1);
+ std::string responseFileName =
+ (responseMode == Link) ? "objects" : "deviceObjects";
+ responseFileName += std::to_string(i + 1);
// Create this response file.
- std::string objects_rsp =
- this->CreateResponseFile(rsp, object_strings[i], makefile_depends);
+ std::string objects_rsp = this->CreateResponseFile(
+ responseFileName, object_strings[i], makefile_depends);
// Separate from previous response file references.
buildObjs += sep;
@@ -2251,7 +2304,7 @@ void cmMakefileTargetGenerator::AddIncludeFlags(std::string& flags,
}
std::string name = cmStrCat("includes_", lang, ".rsp");
std::string arg = std::move(responseFlag) +
- this->CreateResponseFile(name.c_str(), includeFlags,
+ this->CreateResponseFile(name, includeFlags,
this->FlagFileDepends[lang]);
this->LocalGenerator->AppendFlags(flags, arg);
} else {
@@ -2304,3 +2357,22 @@ void cmMakefileTargetGenerator::GenDefFile(
fout << src->GetFullPath() << "\n";
}
}
+
+std::string cmMakefileTargetGenerator::GetResponseFlag(
+ ResponseFlagFor mode) const
+{
+ std::string responseFlag = "@";
+ std::string responseFlagVar;
+
+ auto lang = this->GeneratorTarget->GetLinkerLanguage(this->GetConfigName());
+ if (mode == cmMakefileTargetGenerator::ResponseFlagFor::Link) {
+ responseFlagVar = cmStrCat("CMAKE_", lang, "_RESPONSE_FILE_LINK_FLAG");
+ } else if (mode == cmMakefileTargetGenerator::ResponseFlagFor::DeviceLink) {
+ responseFlagVar = "CMAKE_CUDA_RESPONSE_FILE_DEVICE_LINK_FLAG";
+ }
+
+ if (cmValue p = this->Makefile->GetDefinition(responseFlagVar)) {
+ responseFlag = *p;
+ }
+ return responseFlag;
+}
diff --git a/Source/cmMakefileTargetGenerator.h b/Source/cmMakefileTargetGenerator.h
index cb804e0..dafa650 100644
--- a/Source/cmMakefileTargetGenerator.h
+++ b/Source/cmMakefileTargetGenerator.h
@@ -56,7 +56,7 @@ public:
cmGeneratorTarget* GetGeneratorTarget() { return this->GeneratorTarget; }
- std::string GetConfigName();
+ std::string GetConfigName() const;
protected:
void GetDeviceLinkFlags(std::string& linkFlags,
@@ -157,22 +157,31 @@ protected:
/** Create a response file with the given set of options. Returns
the relative path from the target build working directory to the
response file name. */
- std::string CreateResponseFile(const char* name, std::string const& options,
+ std::string CreateResponseFile(const std::string& name,
+ std::string const& options,
std::vector<std::string>& makefile_depends);
bool CheckUseResponseFileForObjects(std::string const& l) const;
bool CheckUseResponseFileForLibraries(std::string const& l) const;
+ enum ResponseFlagFor
+ {
+ Link,
+ DeviceLink
+ };
+
/** Create list of flags for link libraries. */
void CreateLinkLibs(cmLinkLineComputer* linkLineComputer,
std::string& linkLibs, bool useResponseFile,
- std::vector<std::string>& makefile_depends);
+ std::vector<std::string>& makefile_depends,
+ ResponseFlagFor responseMode = ResponseFlagFor::Link);
/** Create lists of object files for linking and cleaning. */
void CreateObjectLists(bool useLinkScript, bool useArchiveRules,
bool useResponseFile, std::string& buildObjs,
std::vector<std::string>& makefile_depends,
- bool useWatcomQuote);
+ bool useWatcomQuote,
+ ResponseFlagFor responseMode = ResponseFlagFor::Link);
/** Add commands for generate def files */
void GenDefFile(std::vector<std::string>& real_link_commands);
@@ -180,6 +189,9 @@ protected:
void AddIncludeFlags(std::string& flags, const std::string& lang,
const std::string& config) override;
+ /** Return the response flag for the given configuration */
+ std::string GetResponseFlag(ResponseFlagFor mode) const;
+
virtual void CloseFileStreams();
cmLocalUnixMakefileGenerator3* LocalGenerator;
cmGlobalUnixMakefileGenerator3* GlobalGenerator;
diff --git a/Source/cmMessageCommand.cxx b/Source/cmMessageCommand.cxx
index cd57600..fa29ec9 100644
--- a/Source/cmMessageCommand.cxx
+++ b/Source/cmMessageCommand.cxx
@@ -81,94 +81,83 @@ bool cmMessageCommand(std::vector<std::string> const& args,
auto type = MessageType::MESSAGE;
auto fatal = false;
- auto level = cmake::LogLevel::LOG_UNDEFINED;
+ auto level = Message::LogLevel::LOG_UNDEFINED;
auto checkingType = CheckingType::UNDEFINED;
if (*i == "SEND_ERROR") {
type = MessageType::FATAL_ERROR;
- level = cmake::LogLevel::LOG_ERROR;
+ level = Message::LogLevel::LOG_ERROR;
++i;
} else if (*i == "FATAL_ERROR") {
fatal = true;
type = MessageType::FATAL_ERROR;
- level = cmake::LogLevel::LOG_ERROR;
+ level = Message::LogLevel::LOG_ERROR;
++i;
} else if (*i == "WARNING") {
type = MessageType::WARNING;
- level = cmake::LogLevel::LOG_WARNING;
+ level = Message::LogLevel::LOG_WARNING;
++i;
} else if (*i == "AUTHOR_WARNING") {
if (mf.IsSet("CMAKE_SUPPRESS_DEVELOPER_ERRORS") &&
!mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_ERRORS")) {
fatal = true;
type = MessageType::AUTHOR_ERROR;
- level = cmake::LogLevel::LOG_ERROR;
+ level = Message::LogLevel::LOG_ERROR;
} else if (!mf.IsOn("CMAKE_SUPPRESS_DEVELOPER_WARNINGS")) {
type = MessageType::AUTHOR_WARNING;
- level = cmake::LogLevel::LOG_WARNING;
+ level = Message::LogLevel::LOG_WARNING;
} else {
return true;
}
++i;
} else if (*i == "CHECK_START") {
- level = cmake::LogLevel::LOG_STATUS;
+ level = Message::LogLevel::LOG_STATUS;
checkingType = CheckingType::CHECK_START;
++i;
} else if (*i == "CHECK_PASS") {
- level = cmake::LogLevel::LOG_STATUS;
+ level = Message::LogLevel::LOG_STATUS;
checkingType = CheckingType::CHECK_PASS;
++i;
} else if (*i == "CHECK_FAIL") {
- level = cmake::LogLevel::LOG_STATUS;
+ level = Message::LogLevel::LOG_STATUS;
checkingType = CheckingType::CHECK_FAIL;
++i;
} else if (*i == "STATUS") {
- level = cmake::LogLevel::LOG_STATUS;
+ level = Message::LogLevel::LOG_STATUS;
++i;
} else if (*i == "VERBOSE") {
- level = cmake::LogLevel::LOG_VERBOSE;
+ level = Message::LogLevel::LOG_VERBOSE;
++i;
} else if (*i == "DEBUG") {
- level = cmake::LogLevel::LOG_DEBUG;
+ level = Message::LogLevel::LOG_DEBUG;
++i;
} else if (*i == "TRACE") {
- level = cmake::LogLevel::LOG_TRACE;
+ level = Message::LogLevel::LOG_TRACE;
++i;
} else if (*i == "DEPRECATION") {
if (mf.IsOn("CMAKE_ERROR_DEPRECATED")) {
fatal = true;
type = MessageType::DEPRECATION_ERROR;
- level = cmake::LogLevel::LOG_ERROR;
+ level = Message::LogLevel::LOG_ERROR;
} else if (!mf.IsSet("CMAKE_WARN_DEPRECATED") ||
mf.IsOn("CMAKE_WARN_DEPRECATED")) {
type = MessageType::DEPRECATION_WARNING;
- level = cmake::LogLevel::LOG_WARNING;
+ level = Message::LogLevel::LOG_WARNING;
} else {
return true;
}
++i;
} else if (*i == "NOTICE") {
// `NOTICE` message type is going to be output to stderr
- level = cmake::LogLevel::LOG_NOTICE;
+ level = Message::LogLevel::LOG_NOTICE;
++i;
} else {
// Messages w/o any type are `NOTICE`s
- level = cmake::LogLevel::LOG_NOTICE;
+ level = Message::LogLevel::LOG_NOTICE;
}
assert("Message log level expected to be set" &&
- level != cmake::LogLevel::LOG_UNDEFINED);
-
- auto desiredLevel = mf.GetCMakeInstance()->GetLogLevel();
- assert("Expected a valid log level here" &&
- desiredLevel != cmake::LogLevel::LOG_UNDEFINED);
-
- // Command line option takes precedence over the cache variable
- if (!mf.GetCMakeInstance()->WasLogLevelSetViaCLI()) {
- const auto desiredLevelFromCache =
- cmake::StringToLogLevel(mf.GetSafeDefinition("CMAKE_MESSAGE_LOG_LEVEL"));
- if (desiredLevelFromCache != cmake::LogLevel::LOG_UNDEFINED) {
- desiredLevel = desiredLevelFromCache;
- }
- }
+ level != Message::LogLevel::LOG_UNDEFINED);
+
+ Message::LogLevel desiredLevel = mf.GetCurrentLogLevel();
if (desiredLevel < level) {
// Suppress the message
@@ -178,17 +167,17 @@ bool cmMessageCommand(std::vector<std::string> const& args,
auto message = cmJoin(cmMakeRange(i, args.cend()), "");
switch (level) {
- case cmake::LogLevel::LOG_ERROR:
- case cmake::LogLevel::LOG_WARNING:
+ case Message::LogLevel::LOG_ERROR:
+ case Message::LogLevel::LOG_WARNING:
// we've overridden the message type, above, so display it directly
mf.GetMessenger()->DisplayMessage(type, message, mf.GetBacktrace());
break;
- case cmake::LogLevel::LOG_NOTICE:
+ case Message::LogLevel::LOG_NOTICE:
cmSystemTools::Message(IndentText(message, mf));
break;
- case cmake::LogLevel::LOG_STATUS:
+ case Message::LogLevel::LOG_STATUS:
switch (checkingType) {
case CheckingType::CHECK_START:
mf.DisplayStatus(IndentText(message, mf), -1);
@@ -209,9 +198,9 @@ bool cmMessageCommand(std::vector<std::string> const& args,
}
break;
- case cmake::LogLevel::LOG_VERBOSE:
- case cmake::LogLevel::LOG_DEBUG:
- case cmake::LogLevel::LOG_TRACE:
+ case Message::LogLevel::LOG_VERBOSE:
+ case Message::LogLevel::LOG_DEBUG:
+ case Message::LogLevel::LOG_TRACE:
mf.DisplayStatus(IndentText(message, mf), -1);
break;
diff --git a/Source/cmMessageType.h b/Source/cmMessageType.h
index 44de429..decb4b3 100644
--- a/Source/cmMessageType.h
+++ b/Source/cmMessageType.h
@@ -16,3 +16,19 @@ enum class MessageType
DEPRECATION_ERROR,
DEPRECATION_WARNING
};
+
+namespace Message {
+
+/** \brief Define log level constants. */
+enum class LogLevel
+{
+ LOG_UNDEFINED,
+ LOG_ERROR,
+ LOG_WARNING,
+ LOG_NOTICE,
+ LOG_STATUS,
+ LOG_VERBOSE,
+ LOG_DEBUG,
+ LOG_TRACE
+};
+}
diff --git a/Source/cmNinjaNormalTargetGenerator.cxx b/Source/cmNinjaNormalTargetGenerator.cxx
index d4f1608..42f0329 100644
--- a/Source/cmNinjaNormalTargetGenerator.cxx
+++ b/Source/cmNinjaNormalTargetGenerator.cxx
@@ -537,7 +537,6 @@ std::vector<std::string> cmNinjaNormalTargetGenerator::ComputeDeviceLinkCmd()
// this target requires separable cuda compilation
// now build the correct command depending on if the target is
// an executable or a dynamic library.
- std::string linkCmd;
switch (this->GetGeneratorTarget()->GetType()) {
case cmStateEnums::STATIC_LIBRARY:
case cmStateEnums::SHARED_LIBRARY:
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 3fac7f5..e4427f5 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -21,11 +21,17 @@
#include "cmComputeLinkInformation.h"
#include "cmCustomCommandGenerator.h"
+#include "cmExportBuildFileGenerator.h"
+#include "cmExportSet.h"
#include "cmFileSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalNinjaGenerator.h"
+#include "cmInstallCxxModuleBmiGenerator.h"
+#include "cmInstallExportGenerator.h"
+#include "cmInstallFileSetGenerator.h"
+#include "cmInstallGenerator.h"
#include "cmLocalGenerator.h"
#include "cmLocalNinjaGenerator.h"
#include "cmMakefile.h"
@@ -36,12 +42,12 @@
#include "cmRange.h"
#include "cmRulePlaceholderExpander.h"
#include "cmSourceFile.h"
-#include "cmStandardLevelResolver.h"
#include "cmState.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
+#include "cmTargetExport.h"
#include "cmValue.h"
#include "cmake.h"
@@ -153,17 +159,12 @@ std::string cmNinjaTargetGenerator::LanguageDyndepRule(
bool cmNinjaTargetGenerator::NeedCxxModuleSupport(
std::string const& lang, std::string const& config) const
{
- if (lang != "CXX") {
+ if (lang != "CXX"_s) {
return false;
}
- if (!this->Makefile->IsOn("CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP")) {
- return false;
- }
- cmGeneratorTarget const* tgt = this->GetGeneratorTarget();
- cmStandardLevelResolver standardResolver(this->Makefile);
- bool const uses_cxx20 =
- standardResolver.HaveStandardAvailable(tgt, "CXX", config, "cxx_std_20");
- return uses_cxx20 && this->GetGlobalGenerator()->CheckCxxModuleSupport();
+ return this->GetGeneratorTarget()->HaveCxxModuleSupport(config) ==
+ cmGeneratorTarget::Cxx20SupportLevel::Supported &&
+ this->GetGlobalGenerator()->CheckCxxModuleSupport();
}
bool cmNinjaTargetGenerator::NeedDyndep(std::string const& lang,
@@ -255,51 +256,53 @@ std::string cmNinjaTargetGenerator::ComputeFlagsForObject(
flags, genexInterpreter.Evaluate(pchOptions, COMPILE_OPTIONS));
}
- if (this->NeedCxxModuleSupport(language, config)) {
- auto const& path = source->GetFullPath();
- auto const* tgt = this->GeneratorTarget->Target;
+ auto const& path = source->GetFullPath();
+ auto const* tgt = this->GeneratorTarget->Target;
- std::string file_set_type;
+ std::string file_set_type;
- for (auto const& name : tgt->GetAllFileSetNames()) {
- auto const* file_set = tgt->GetFileSet(name);
- if (!file_set) {
- this->GetMakefile()->IssueMessage(
- MessageType::INTERNAL_ERROR,
- cmStrCat("Target `", tgt->GetName(),
- "` is tracked to have file set `", name,
- "`, but it was not found."));
- continue;
- }
+ for (auto const& name : tgt->GetAllFileSetNames()) {
+ auto const* file_set = tgt->GetFileSet(name);
+ if (!file_set) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"", name,
+ "\", but it was not found."));
+ continue;
+ }
- auto fileEntries = file_set->CompileFileEntries();
- auto directoryEntries = file_set->CompileDirectoryEntries();
- auto directories = file_set->EvaluateDirectoryEntries(
- directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, this->LocalGenerator, config, this->GeneratorTarget);
- std::map<std::string, std::vector<std::string>> files;
- for (auto const& entry : fileEntries) {
- file_set->EvaluateFileEntry(directories, files, entry,
- this->LocalGenerator, config,
- this->GeneratorTarget);
- }
+ std::map<std::string, std::vector<std::string>> files;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files, entry,
+ this->LocalGenerator, config,
+ this->GeneratorTarget);
+ }
- for (auto const& it : files) {
- for (auto const& filename : it.second) {
- if (filename == path) {
- file_set_type = file_set->GetType();
- break;
- }
+ for (auto const& it : files) {
+ for (auto const& filename : it.second) {
+ if (filename == path) {
+ file_set_type = file_set->GetType();
+ break;
}
}
+ }
- if (!file_set_type.empty()) {
- std::string source_type_var = cmStrCat(
- "CMAKE_EXPERIMENTAL_CXX_MODULE_SOURCE_TYPE_FLAG_", file_set_type);
- cmMakefile* mf = this->GetMakefile();
- if (cmValue source_type_flag = mf->GetDefinition(source_type_var)) {
- this->LocalGenerator->AppendFlags(flags, *source_type_flag);
- }
+ if (file_set_type == "CXX_MODULES"_s ||
+ file_set_type == "CXX_MODULE_HEADER_UNITS"_s) {
+ if (source->GetLanguage() != "CXX"_s) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat(
+ "Target \"", tgt->GetName(), "\" contains the source\n ", path,
+ "\nin a file set of type \"", file_set_type,
+ R"(" but the source is not classified as a "CXX" source.)"));
+ continue;
}
}
}
@@ -909,8 +912,10 @@ void cmNinjaTargetGenerator::WriteCompileRule(const std::string& lang,
lang == "OBJCXX")) {
std::string const clauncher_prop = cmStrCat(lang, "_COMPILER_LAUNCHER");
cmValue clauncher = this->GeneratorTarget->GetProperty(clauncher_prop);
- if (cmNonempty(clauncher)) {
- compilerLauncher = *clauncher;
+ std::string evaluatedClauncher = cmGeneratorExpression::Evaluate(
+ *clauncher, this->LocalGenerator, config);
+ if (!evaluatedClauncher.empty()) {
+ compilerLauncher = evaluatedClauncher;
}
}
@@ -1038,6 +1043,8 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatements(
const std::string& config, const std::string& fileConfig,
bool firstForConfig)
{
+ this->GeneratorTarget->CheckCxxModuleStatus(config);
+
// Write comments.
cmGlobalNinjaGenerator::WriteDivider(this->GetImplFileStream(fileConfig));
this->GetImplFileStream(fileConfig)
@@ -1338,9 +1345,11 @@ void cmNinjaTargetGenerator::WriteObjectBuildStatement(
}
}
- this->ExportObjectCompileCommand(
- language, sourceFilePath, objectDir, objectFileName, objectFileDir,
- vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"], config);
+ if (firstForConfig) {
+ this->ExportObjectCompileCommand(
+ language, sourceFilePath, objectDir, objectFileName, objectFileDir,
+ vars["FLAGS"], vars["DEFINES"], vars["INCLUDES"], config);
+ }
objBuild.Outputs.push_back(objectFileName);
if (firstForConfig) {
@@ -1616,8 +1625,9 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
mod_dir = this->GeneratorTarget->GetFortranModuleDirectory(
this->Makefile->GetHomeOutputDirectory());
} else if (lang == "CXX") {
- mod_dir =
- cmSystemTools::CollapseFullPath(this->GeneratorTarget->ObjectDirectory);
+ mod_dir = this->GetGlobalGenerator()->ExpandCFGIntDir(
+ cmSystemTools::CollapseFullPath(this->GeneratorTarget->ObjectDirectory),
+ config);
}
if (mod_dir.empty()) {
mod_dir = this->Makefile->GetCurrentBinaryDirectory();
@@ -1654,6 +1664,215 @@ void cmNinjaTargetGenerator::WriteTargetDependInfo(std::string const& lang,
tdi_linked_target_dirs.append(l);
}
+ cmTarget* tgt = this->GeneratorTarget->Target;
+ auto all_file_sets = tgt->GetAllFileSetNames();
+ Json::Value& tdi_cxx_module_info = tdi["cxx-modules"] = Json::objectValue;
+ for (auto const& file_set_name : all_file_sets) {
+ auto* file_set = tgt->GetFileSet(file_set_name);
+ if (!file_set) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" is tracked to have file set \"", file_set_name,
+ "\", but it was not found."));
+ continue;
+ }
+ auto fs_type = file_set->GetType();
+ // We only care about C++ module sources here.
+ if (fs_type != "CXX_MODULES"_s) {
+ continue;
+ }
+
+ auto fileEntries = file_set->CompileFileEntries();
+ auto directoryEntries = file_set->CompileDirectoryEntries();
+
+ auto directories = file_set->EvaluateDirectoryEntries(
+ directoryEntries, this->GeneratorTarget->LocalGenerator, config,
+ this->GeneratorTarget);
+ std::map<std::string, std::vector<std::string>> files_per_dirs;
+ for (auto const& entry : fileEntries) {
+ file_set->EvaluateFileEntry(directories, files_per_dirs, entry,
+ this->GeneratorTarget->LocalGenerator,
+ config, this->GeneratorTarget);
+ }
+
+ std::map<std::string, cmSourceFile const*> sf_map;
+ {
+ std::vector<cmSourceFile const*> objectSources;
+ this->GeneratorTarget->GetObjectSources(objectSources, config);
+ for (auto const* sf : objectSources) {
+ auto full_path = sf->GetFullPath();
+ if (full_path.empty()) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(),
+ "\" has a full path-less source file."));
+ continue;
+ }
+ sf_map[full_path] = sf;
+ }
+ }
+
+ Json::Value fs_dest = Json::nullValue;
+ for (auto const& ig : this->GetMakefile()->GetInstallGenerators()) {
+ if (auto const* fsg =
+ dynamic_cast<cmInstallFileSetGenerator const*>(ig.get())) {
+ if (fsg->GetTarget() == this->GeneratorTarget &&
+ fsg->GetFileSet() == file_set) {
+ fs_dest = fsg->GetDestination(config);
+ continue;
+ }
+ }
+ }
+
+ for (auto const& files_per_dir : files_per_dirs) {
+ for (auto const& file : files_per_dir.second) {
+ auto lookup = sf_map.find(file);
+ if (lookup == sf_map.end()) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
+ file,
+ R"(" which is not in any of its "FILE_SET BASE_DIRS".)"));
+ continue;
+ }
+
+ auto const* sf = lookup->second;
+
+ if (!sf) {
+ this->GetMakefile()->IssueMessage(
+ MessageType::INTERNAL_ERROR,
+ cmStrCat("Target \"", tgt->GetName(), "\" has source file \"",
+ file, "\" which has not been tracked properly."));
+ continue;
+ }
+
+ auto obj_path = this->GetObjectFilePath(sf, config);
+ Json::Value& tdi_module_info = tdi_cxx_module_info[obj_path] =
+ Json::objectValue;
+
+ tdi_module_info["source"] = file;
+ tdi_module_info["relative-directory"] = files_per_dir.first;
+ tdi_module_info["name"] = file_set->GetName();
+ tdi_module_info["type"] = file_set->GetType();
+ tdi_module_info["visibility"] =
+ std::string(cmFileSetVisibilityToName(file_set->GetVisibility()));
+ tdi_module_info["destination"] = fs_dest;
+ }
+ }
+ }
+
+ tdi["config"] = config;
+
+ // Add information about the export sets that this target is a member of.
+ Json::Value& tdi_exports = tdi["exports"] = Json::arrayValue;
+ std::string export_name = this->GeneratorTarget->GetExportName();
+
+ cmInstallCxxModuleBmiGenerator const* bmi_gen = nullptr;
+ for (auto const& ig : this->GetMakefile()->GetInstallGenerators()) {
+ if (auto const* bmig =
+ dynamic_cast<cmInstallCxxModuleBmiGenerator const*>(ig.get())) {
+ if (bmig->GetTarget() == this->GeneratorTarget) {
+ bmi_gen = bmig;
+ continue;
+ }
+ }
+ }
+ if (bmi_gen) {
+ Json::Value tdi_bmi_info = Json::objectValue;
+
+ tdi_bmi_info["permissions"] = bmi_gen->GetFilePermissions();
+ tdi_bmi_info["destination"] = bmi_gen->GetDestination(config);
+ const char* msg_level = "";
+ switch (bmi_gen->GetMessageLevel()) {
+ case cmInstallGenerator::MessageDefault:
+ break;
+ case cmInstallGenerator::MessageAlways:
+ msg_level = "MESSAGE_ALWAYS";
+ break;
+ case cmInstallGenerator::MessageLazy:
+ msg_level = "MESSAGE_LAZY";
+ break;
+ case cmInstallGenerator::MessageNever:
+ msg_level = "MESSAGE_NEVER";
+ break;
+ }
+ tdi_bmi_info["message-level"] = msg_level;
+ tdi_bmi_info["script-location"] = bmi_gen->GetScriptLocation(config);
+
+ tdi["bmi-installation"] = tdi_bmi_info;
+ } else {
+ tdi["bmi-installation"] = Json::nullValue;
+ }
+
+ auto const& all_install_exports =
+ this->GetGlobalGenerator()->GetExportSets();
+ for (auto const& exp : all_install_exports) {
+ // Ignore exports sets which are not for this target.
+ auto const& targets = exp.second.GetTargetExports();
+ auto tgt_export =
+ std::find_if(targets.begin(), targets.end(),
+ [this](std::unique_ptr<cmTargetExport> const& te) {
+ return te->Target == this->GeneratorTarget;
+ });
+ if (tgt_export == targets.end()) {
+ continue;
+ }
+
+ auto const* installs = exp.second.GetInstallations();
+ for (auto const* install : *installs) {
+ Json::Value tdi_export_info = Json::objectValue;
+
+ auto const& ns = install->GetNamespace();
+ auto const& dest = install->GetDestination();
+ auto const& cxxm_dir = install->GetCxxModuleDirectory();
+ auto const& export_prefix = install->GetTempDir();
+
+ tdi_export_info["namespace"] = ns;
+ tdi_export_info["export-name"] = export_name;
+ tdi_export_info["destination"] = dest;
+ tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
+ tdi_export_info["export-prefix"] = export_prefix;
+ tdi_export_info["install"] = true;
+
+ tdi_exports.append(tdi_export_info);
+ }
+ }
+
+ auto const& all_build_exports =
+ this->GetMakefile()->GetExportBuildFileGenerators();
+ for (auto const& exp : all_build_exports) {
+ std::vector<std::string> targets;
+ exp->GetTargets(targets);
+
+ // Ignore exports sets which are not for this target.
+ auto const& name = this->GeneratorTarget->GetName();
+ bool has_current_target =
+ std::any_of(targets.begin(), targets.end(),
+ [name](std::string const& tname) { return tname == name; });
+ if (!has_current_target) {
+ continue;
+ }
+
+ Json::Value tdi_export_info = Json::objectValue;
+
+ auto const& ns = exp->GetNamespace();
+ auto const& main_fn = exp->GetMainExportFileName();
+ auto const& cxxm_dir = exp->GetCxxModuleDirectory();
+ auto dest = cmsys::SystemTools::GetParentDirectory(main_fn);
+ auto const& export_prefix =
+ cmSystemTools::GetFilenamePath(exp->GetMainExportFileName());
+
+ tdi_export_info["namespace"] = ns;
+ tdi_export_info["export-name"] = export_name;
+ tdi_export_info["destination"] = dest;
+ tdi_export_info["cxx-module-info-dir"] = cxxm_dir;
+ tdi_export_info["export-prefix"] = export_prefix;
+ tdi_export_info["install"] = false;
+
+ tdi_exports.append(tdi_export_info);
+ }
+
std::string const tdin = this->GetTargetDependInfoPath(lang, config);
cmGeneratedFileStream tdif(tdin);
tdif << tdi;
diff --git a/Source/cmParseArgumentsCommand.cxx b/Source/cmParseArgumentsCommand.cxx
index 95f3e7e..7e19566 100644
--- a/Source/cmParseArgumentsCommand.cxx
+++ b/Source/cmParseArgumentsCommand.cxx
@@ -10,6 +10,7 @@
#include <cm/string_view>
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
@@ -41,11 +42,18 @@ namespace {
using options_map = std::map<std::string, bool>;
using single_map = std::map<std::string, std::string>;
-using multi_map = std::map<std::string, std::vector<std::string>>;
-using options_set = std::set<std::string>;
+using multi_map =
+ std::map<std::string, ArgumentParser::NonEmpty<std::vector<std::string>>>;
+using options_set = std::set<cm::string_view>;
struct UserArgumentParser : public cmArgumentParser<void>
{
+ void BindKeywordsMissingValue(std::vector<cm::string_view>& ref)
+ {
+ this->cmArgumentParser<void>::BindKeywordMissingValue(
+ [&ref](Instance&, cm::string_view arg) { ref.emplace_back(arg); });
+ }
+
template <typename T, typename H>
void Bind(std::vector<std::string> const& names,
std::map<std::string, T>& ref, H duplicateKey)
@@ -208,9 +216,10 @@ bool cmParseArgumentsCommand(std::vector<std::string> const& args,
}
}
- std::vector<std::string> keywordsMissingValues;
+ std::vector<cm::string_view> keywordsMissingValues;
+ parser.BindKeywordsMissingValue(keywordsMissingValues);
- parser.Parse(list, &unparsed, &keywordsMissingValues);
+ parser.Parse(list, &unparsed);
PassParsedArguments(
prefix, status.GetMakefile(), options, singleValArgs, multiValArgs,
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index cb7402c..fdda31e 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -421,7 +421,9 @@ class cmMakefile;
SELECT( \
POLICY, CMP0139, \
"The if() command supports path comparisons using PATH_EQUAL operator.", \
- 3, 24, 0, cmPolicies::WARN)
+ 3, 24, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0140, "The return() command checks its arguments.", 3, \
+ 25, 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 40f3ab5..6c500b0 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -1847,8 +1847,7 @@ void cmQtAutoGenInitializer::AddToSourceGroup(std::string const& fileName,
void cmQtAutoGenInitializer::AddCleanFile(std::string const& fileName)
{
- this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName,
- false);
+ this->GenTarget->Target->AppendProperty("ADDITIONAL_CLEAN_FILES", fileName);
}
void cmQtAutoGenInitializer::ConfigFileNames(ConfigString& configString,
diff --git a/Source/cmReturnCommand.cxx b/Source/cmReturnCommand.cxx
index 5905669..765b772 100644
--- a/Source/cmReturnCommand.cxx
+++ b/Source/cmReturnCommand.cxx
@@ -2,12 +2,52 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmReturnCommand.h"
+#include <cm/string_view>
+#include <cmext/string_view>
+
#include "cmExecutionStatus.h"
+#include "cmMakefile.h"
+#include "cmMessageType.h"
+#include "cmPolicies.h"
+#include "cmStringAlgorithms.h"
+#include "cmSystemTools.h"
// cmReturnCommand
-bool cmReturnCommand(std::vector<std::string> const&,
+bool cmReturnCommand(std::vector<std::string> const& args,
cmExecutionStatus& status)
{
- status.SetReturnInvoked();
+ if (!args.empty()) {
+ switch (status.GetMakefile().GetPolicyStatus(cmPolicies::CMP0140)) {
+ case cmPolicies::WARN:
+ status.GetMakefile().IssueMessage(
+ MessageType::AUTHOR_WARNING,
+ cmStrCat(
+ cmPolicies::GetPolicyWarning(cmPolicies::CMP0140), '\n',
+ "return() checks its arguments when the policy is set to NEW. "
+ "Since the policy is not set the OLD behavior will be used so "
+ "the arguments will be ignored."));
+ CM_FALLTHROUGH;
+ case cmPolicies::OLD:
+ return true;
+ case cmPolicies::REQUIRED_IF_USED:
+ case cmPolicies::REQUIRED_ALWAYS:
+ status.GetMakefile().IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat('\n', cmPolicies::GetPolicyWarning(cmPolicies::CMP0140)));
+ cmSystemTools::SetFatalErrorOccurred();
+ return false;
+ default:
+ break;
+ }
+ if (args[0] != "PROPAGATE"_s) {
+ status.SetError(
+ cmStrCat("called with unsupported argument \"", args[0], '"'));
+ cmSystemTools::SetFatalErrorOccurred();
+ return false;
+ }
+ status.SetReturnInvoked({ args.begin() + 1, args.end() });
+ } else {
+ status.SetReturnInvoked();
+ }
return true;
}
diff --git a/Source/cmScanDepFormat.cxx b/Source/cmScanDepFormat.cxx
index 82a374a..ec53af5 100644
--- a/Source/cmScanDepFormat.cxx
+++ b/Source/cmScanDepFormat.cxx
@@ -5,6 +5,7 @@
#include <cctype>
#include <cstdio>
+#include <iostream>
#include <utility>
#include <cm/optional>
@@ -188,6 +189,19 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp,
return false;
}
+ if (provide.isMember("is-interface")) {
+ Json::Value const& is_interface = provide["is-interface"];
+ if (!is_interface.isBool()) {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
+ ": is-interface is not a boolean"));
+ return false;
+ }
+ provide_info.IsInterface = is_interface.asBool();
+ } else {
+ provide_info.IsInterface = true;
+ }
+
info->Provides.push_back(provide_info);
}
}
@@ -267,6 +281,27 @@ bool cmScanDepFormat_P1689_Parse(std::string const& arg_pp,
info->Requires.push_back(require_info);
}
}
+
+ // MSVC 17.3 toolchain bug. Remove when 17.4 is available.
+ if (rule.isMember("is-interface")) {
+ std::cerr
+ << "warning: acknowledging an VS 17.3 toolchain bug; accepting "
+ "until a new release which fixes it is available"
+ << std::endl;
+
+ Json::Value const& is_interface_json = rule["is-interface"];
+ if (!is_interface_json.isBool()) {
+ cmSystemTools::Error(
+ cmStrCat("-E cmake_ninja_dyndep failed to parse ", arg_pp,
+ ": is-interface is not a boolean"));
+ return false;
+ }
+ bool is_interface = is_interface_json.asBool();
+
+ for (auto& provide : info->Provides) {
+ provide.IsInterface = is_interface;
+ }
+ }
}
}
@@ -308,6 +343,8 @@ bool cmScanDepFormat_P1689_Write(std::string const& path,
provide_obj["source-path"] = EncodeFilename(provide.SourcePath);
}
+ provide_obj["is-interface"] = provide.IsInterface;
+
provides.append(provide_obj);
}
diff --git a/Source/cmScanDepFormat.h b/Source/cmScanDepFormat.h
index dae28d9..dc55bf1 100644
--- a/Source/cmScanDepFormat.h
+++ b/Source/cmScanDepFormat.h
@@ -18,6 +18,11 @@ struct cmSourceReqInfo
std::string SourcePath;
std::string CompiledModulePath;
bool UseSourcePath = false;
+
+ // Provides-only fields.
+ bool IsInterface = true;
+
+ // Requires-only fields.
LookupMethod Method = LookupMethod::ByName;
};
diff --git a/Source/cmScriptGenerator.cxx b/Source/cmScriptGenerator.cxx
index 166ee56..32f9bec 100644
--- a/Source/cmScriptGenerator.cxx
+++ b/Source/cmScriptGenerator.cxx
@@ -133,7 +133,7 @@ void cmScriptGenerator::GenerateScriptActionsOnce(std::ostream& os,
std::string config_test = this->CreateConfigTest(this->Configurations);
os << indent << "if(" << config_test << ")\n";
this->GenerateScriptActions(os, indent.Next());
- os << indent << "endif(" << config_test << ")\n";
+ os << indent << "endif()\n";
}
}
diff --git a/Source/cmSetPropertyCommand.cxx b/Source/cmSetPropertyCommand.cxx
index db10cd4..521cf63 100644
--- a/Source/cmSetPropertyCommand.cxx
+++ b/Source/cmSetPropertyCommand.cxx
@@ -9,6 +9,7 @@
#include "cmExecutionStatus.h"
#include "cmGlobalGenerator.h"
#include "cmInstalledFile.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -561,7 +562,8 @@ bool HandleTarget(cmTarget* target, cmMakefile& makefile,
{
// Set or append the property.
if (appendMode) {
- target->AppendProperty(propertyName, propertyValue, appendAsString);
+ target->AppendProperty(propertyName, propertyValue,
+ makefile.GetBacktrace(), appendAsString);
} else {
if (remove) {
target->SetProperty(propertyName, nullptr);
diff --git a/Source/cmStandardLevelResolver.cxx b/Source/cmStandardLevelResolver.cxx
index 785f356..d2eac0c 100644
--- a/Source/cmStandardLevelResolver.cxx
+++ b/Source/cmStandardLevelResolver.cxx
@@ -18,6 +18,7 @@
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmPolicies.h"
@@ -378,25 +379,29 @@ std::unordered_map<std::string, StandardLevelComputer>
"C", std::vector<int>{ 90, 99, 11, 17, 23 },
std::vector<std::string>{ "90", "99", "11", "17", "23" } } },
{ "CXX",
- StandardLevelComputer{
- "CXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
- std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } },
+ StandardLevelComputer{ "CXX",
+ std::vector<int>{ 98, 11, 14, 17, 20, 23, 26 },
+ std::vector<std::string>{ "98", "11", "14", "17",
+ "20", "23", "26" } } },
{ "CUDA",
- StandardLevelComputer{
- "CUDA", std::vector<int>{ 03, 11, 14, 17, 20, 23 },
- std::vector<std::string>{ "03", "11", "14", "17", "20", "23" } } },
+ StandardLevelComputer{ "CUDA",
+ std::vector<int>{ 03, 11, 14, 17, 20, 23, 26 },
+ std::vector<std::string>{ "03", "11", "14", "17",
+ "20", "23", "26" } } },
{ "OBJC",
StandardLevelComputer{
"OBJC", std::vector<int>{ 90, 99, 11, 17, 23 },
std::vector<std::string>{ "90", "99", "11", "17", "23" } } },
{ "OBJCXX",
- StandardLevelComputer{
- "OBJCXX", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
- std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } },
+ StandardLevelComputer{ "OBJCXX",
+ std::vector<int>{ 98, 11, 14, 17, 20, 23, 26 },
+ std::vector<std::string>{ "98", "11", "14", "17",
+ "20", "23", "26" } } },
{ "HIP",
- StandardLevelComputer{
- "HIP", std::vector<int>{ 98, 11, 14, 17, 20, 23 },
- std::vector<std::string>{ "98", "11", "14", "17", "20", "23" } } }
+ StandardLevelComputer{ "HIP",
+ std::vector<int>{ 98, 11, 14, 17, 20, 23, 26 },
+ std::vector<std::string>{ "98", "11", "14", "17",
+ "20", "23", "26" } } }
};
}
@@ -416,7 +421,8 @@ bool cmStandardLevelResolver::AddRequiredTargetFeature(
cmTarget* target, const std::string& feature, std::string* error) const
{
if (cmGeneratorExpression::Find(feature) != std::string::npos) {
- target->AppendProperty("COMPILE_FEATURES", feature);
+ target->AppendProperty("COMPILE_FEATURES", feature,
+ this->Makefile->GetBacktrace());
return true;
}
@@ -426,7 +432,8 @@ bool cmStandardLevelResolver::AddRequiredTargetFeature(
return false;
}
- target->AppendProperty("COMPILE_FEATURES", feature);
+ target->AppendProperty("COMPILE_FEATURES", feature,
+ this->Makefile->GetBacktrace());
// FIXME: Add a policy to avoid updating the <LANG>_STANDARD target
// property due to COMPILE_FEATURES. The language standard selection
diff --git a/Source/cmStringCommand.cxx b/Source/cmStringCommand.cxx
index c3ee695..c12d1fe 100644
--- a/Source/cmStringCommand.cxx
+++ b/Source/cmStringCommand.cxx
@@ -143,7 +143,8 @@ bool HandleHexCommand(std::vector<std::string> const& args,
std::string::size_type hexIndex = 0;
for (auto const& c : instr) {
- sprintf(&output[hexIndex], "%.2x", static_cast<unsigned char>(c) & 0xFF);
+ snprintf(&output[hexIndex], 3, "%.2x",
+ static_cast<unsigned char>(c) & 0xFF);
hexIndex += 2;
}
@@ -1013,7 +1014,7 @@ int ParseIndex(
Json::ArrayIndex index = static_cast<Json::ArrayIndex>(lindex);
if (index >= max) {
cmAlphaNum sizeStr{ max };
- throw json_error({ "expected an index less then "_s, sizeStr.View(),
+ throw json_error({ "expected an index less than "_s, sizeStr.View(),
" got '"_s, str, "'"_s },
progress);
}
diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx
index f077801..8e77afa 100644
--- a/Source/cmSystemTools.cxx
+++ b/Source/cmSystemTools.cxx
@@ -11,11 +11,17 @@
// NOLINTNEXTLINE(bugprone-reserved-identifier)
# define _XOPEN_SOURCE 700
#endif
+#if defined(__APPLE__)
+// Restore Darwin APIs removed by _POSIX_C_SOURCE.
+// NOLINTNEXTLINE(bugprone-reserved-identifier)
+# define _DARWIN_C_SOURCE
+#endif
#include "cmSystemTools.h"
#include <cm/optional>
#include <cmext/algorithm>
+#include <cmext/string_view>
#include <cm3p/uv.h>
@@ -87,7 +93,6 @@
# include <unistd.h>
# include <sys/time.h>
-# include <sys/types.h>
#endif
#if defined(_WIN32) && \
@@ -1000,6 +1005,93 @@ void cmSystemTools::InitializeLibUV()
#endif
}
+#if defined(_WIN32)
+# include <random>
+
+# include <wctype.h>
+# ifdef _MSC_VER
+using mode_t = cmSystemTools::SystemTools::mode_t;
+# endif
+#else
+# include <sys/stat.h>
+#endif
+
+inline int Mkdir(const char* dir, const mode_t* mode)
+{
+#if defined(_WIN32)
+ int ret = _wmkdir(cmSystemTools::ConvertToWindowsExtendedPath(dir).c_str());
+ if (ret == 0 && mode)
+ cmSystemTools::SystemTools::SetPermissions(dir, *mode);
+ return ret;
+#else
+ return mkdir(dir, mode ? *mode : 0777);
+#endif
+}
+
+cmsys::Status cmSystemTools::MakeTempDirectory(std::string& path,
+ const mode_t* mode)
+{
+ if (path.empty()) {
+ return cmsys::Status::POSIX(EINVAL);
+ }
+ return cmSystemTools::MakeTempDirectory(&path.front(), mode);
+}
+
+cmsys::Status cmSystemTools::MakeTempDirectory(char* path, const mode_t* mode)
+{
+ if (!path) {
+ return cmsys::Status::POSIX(EINVAL);
+ }
+
+ // verify that path ends with "XXXXXX"
+ const auto l = std::strlen(path);
+ if (!cmHasLiteralSuffix(cm::string_view{ path, l }, "XXXXXX")) {
+ return cmsys::Status::POSIX(EINVAL);
+ }
+
+ // create parent directories
+ auto* sep = path;
+ while ((sep = strchr(sep, '/'))) {
+ // all underlying functions use C strings,
+ // so temporarily end the string here
+ *sep = '\0';
+ Mkdir(path, mode);
+
+ *sep = '/';
+ ++sep;
+ }
+
+#ifdef _WIN32
+ const int nchars = 36;
+ const char chars[nchars + 1] = "abcdefghijklmnopqrstuvwxyz0123456789";
+
+ std::random_device rd;
+ std::mt19937 rg{ rd() };
+ std::uniform_int_distribution<int> dist{ 0, nchars - 1 };
+
+ for (auto tries = 100; tries; --tries) {
+ for (auto n = l - 6; n < l; ++n) {
+ path[n] = chars[dist(rg)];
+ }
+ if (Mkdir(path, mode) == 0) {
+ return cmsys::Status::Success();
+ } else if (errno != EEXIST) {
+ return cmsys::Status::POSIX_errno();
+ }
+ }
+ return cmsys::Status::POSIX(EAGAIN);
+#else
+ if (mkdtemp(path)) {
+ if (mode) {
+ chmod(path, *mode);
+ }
+ } else {
+ return cmsys::Status::POSIX_errno();
+ }
+ return cmsys::Status::Success();
+#endif
+}
+
#ifdef _WIN32
namespace {
bool cmMoveFile(std::wstring const& oldname, std::wstring const& newname,
@@ -1256,7 +1348,7 @@ std::string cmSystemTools::ComputeCertificateThumbprint(
certContext, CERT_HASH_PROP_ID, hashData, &hashLength)) {
for (DWORD i = 0; i < hashLength; i++) {
// Convert each byte to hexadecimal
- sprintf(pHashPrint, "%02X", hashData[i]);
+ snprintf(pHashPrint, 3, "%02X", hashData[i]);
pHashPrint += 2;
}
*pHashPrint = '\0';
@@ -1539,8 +1631,7 @@ std::string cmSystemTools::RelativeIfUnder(std::string const& top,
bool cmSystemTools::UnsetEnv(const char* value)
{
# if !defined(HAVE_UNSETENV)
- std::string var = cmStrCat(value, '=');
- return cmSystemTools::PutEnv(var);
+ return cmSystemTools::UnPutEnv(value);
# else
unsetenv(value);
return true;
@@ -1564,6 +1655,144 @@ void cmSystemTools::AppendEnv(std::vector<std::string> const& env)
}
}
+void cmSystemTools::EnvDiff::AppendEnv(std::vector<std::string> const& env)
+{
+ for (std::string const& eit : env) {
+ this->PutEnv(eit);
+ }
+}
+
+void cmSystemTools::EnvDiff::PutEnv(const std::string& env)
+{
+ auto const eq_loc = env.find('=');
+ if (eq_loc != std::string::npos) {
+ std::string name = env.substr(0, eq_loc);
+ diff[name] = env.substr(eq_loc + 1);
+ } else {
+ this->UnPutEnv(env);
+ }
+}
+
+void cmSystemTools::EnvDiff::UnPutEnv(const std::string& env)
+{
+ diff[env] = {};
+}
+
+bool cmSystemTools::EnvDiff::ParseOperation(const std::string& envmod)
+{
+ char path_sep = GetSystemPathlistSeparator();
+
+ auto apply_diff = [this](const std::string& name,
+ std::function<void(std::string&)> const& apply) {
+ cm::optional<std::string> old_value = diff[name];
+ std::string output;
+ if (old_value) {
+ output = *old_value;
+ } else {
+ const char* curval = cmSystemTools::GetEnv(name);
+ if (curval) {
+ output = curval;
+ }
+ }
+ apply(output);
+ diff[name] = output;
+ };
+
+ // Split on `=`
+ auto const eq_loc = envmod.find_first_of('=');
+ if (eq_loc == std::string::npos) {
+ cmSystemTools::Error(cmStrCat(
+ "Error: Missing `=` after the variable name in: ", envmod, '\n'));
+ return false;
+ }
+
+ auto const name = envmod.substr(0, eq_loc);
+
+ // Split value on `:`
+ auto const op_value_start = eq_loc + 1;
+ auto const colon_loc = envmod.find_first_of(':', op_value_start);
+ if (colon_loc == std::string::npos) {
+ cmSystemTools::Error(
+ cmStrCat("Error: Missing `:` after the operation in: ", envmod, '\n'));
+ return false;
+ }
+ auto const op = envmod.substr(op_value_start, colon_loc - op_value_start);
+
+ auto const value_start = colon_loc + 1;
+ auto const value = envmod.substr(value_start);
+
+ // Determine what to do with the operation.
+ if (op == "reset"_s) {
+ auto entry = diff.find(name);
+ if (entry != diff.end()) {
+ diff.erase(entry);
+ }
+ } else if (op == "set"_s) {
+ diff[name] = value;
+ } else if (op == "unset"_s) {
+ diff[name] = {};
+ } else if (op == "string_append"_s) {
+ apply_diff(name, [&value](std::string& output) { output += value; });
+ } else if (op == "string_prepend"_s) {
+ apply_diff(name,
+ [&value](std::string& output) { output.insert(0, value); });
+ } else if (op == "path_list_append"_s) {
+ apply_diff(name, [&value, path_sep](std::string& output) {
+ if (!output.empty()) {
+ output += path_sep;
+ }
+ output += value;
+ });
+ } else if (op == "path_list_prepend"_s) {
+ apply_diff(name, [&value, path_sep](std::string& output) {
+ if (!output.empty()) {
+ output.insert(output.begin(), path_sep);
+ }
+ output.insert(0, value);
+ });
+ } else if (op == "cmake_list_append"_s) {
+ apply_diff(name, [&value](std::string& output) {
+ if (!output.empty()) {
+ output += ';';
+ }
+ output += value;
+ });
+ } else if (op == "cmake_list_prepend"_s) {
+ apply_diff(name, [&value](std::string& output) {
+ if (!output.empty()) {
+ output.insert(output.begin(), ';');
+ }
+ output.insert(0, value);
+ });
+ } else {
+ cmSystemTools::Error(cmStrCat(
+ "Error: Unrecognized environment manipulation argument: ", op, '\n'));
+ return false;
+ }
+
+ return true;
+}
+
+void cmSystemTools::EnvDiff::ApplyToCurrentEnv(std::ostringstream* measurement)
+{
+ for (auto const& env_apply : diff) {
+ if (env_apply.second) {
+ auto const env_update =
+ cmStrCat(env_apply.first, '=', *env_apply.second);
+ cmSystemTools::PutEnv(env_update);
+ if (measurement) {
+ *measurement << env_update << std::endl;
+ }
+ } else {
+ cmSystemTools::UnsetEnv(env_apply.first.c_str());
+ if (measurement) {
+ // Signify that this variable is being actively unset
+ *measurement << '#' << env_apply.first << "=\n";
+ }
+ }
+ }
+}
+
cmSystemTools::SaveRestoreEnvironment::SaveRestoreEnvironment()
{
this->Env = cmSystemTools::GetEnvironmentVariables();
diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h
index ec650f7..b02a977 100644
--- a/Source/cmSystemTools.h
+++ b/Source/cmSystemTools.h
@@ -4,11 +4,18 @@
#include "cmConfigure.h" // IWYU pragma: keep
+#if !defined(_WIN32)
+# include <sys/types.h>
+#endif
+
#include <cstddef>
#include <functional>
+#include <map>
+#include <sstream>
#include <string>
#include <vector>
+#include <cm/optional>
#include <cm/string_view>
#include "cmsys/Process.h"
@@ -148,6 +155,27 @@ public:
Failure,
};
+#if defined(_MSC_VER)
+ /** Visual C++ does not define mode_t. */
+ using mode_t = unsigned short;
+#endif
+
+ /**
+ * Make a new temporary directory. The path must end in "XXXXXX", and will
+ * be modified to reflect the name of the directory created. This function
+ * is similar to POSIX mkdtemp (and is implemented using the same where that
+ * function is available).
+ *
+ * This function can make a full path even if none of the directories existed
+ * prior to calling this function.
+ *
+ * Note that this function may modify \p path even if it does not succeed.
+ */
+ static cmsys::Status MakeTempDirectory(char* path,
+ const mode_t* mode = nullptr);
+ static cmsys::Status MakeTempDirectory(std::string& path,
+ const mode_t* mode = nullptr);
+
/** Copy a file. */
static bool CopySingleFile(const std::string& oldname,
const std::string& newname);
@@ -377,6 +405,42 @@ public:
/** Append multiple variables to the current environment. */
static void AppendEnv(std::vector<std::string> const& env);
+ /**
+ * Helper class to represent an environment diff directly. This is to avoid
+ * repeated in-place environment modification (i.e. via setenv/putenv), which
+ * could be slow.
+ */
+ class EnvDiff
+ {
+ public:
+ /** Append multiple variables to the current environment diff */
+ void AppendEnv(std::vector<std::string> const& env);
+
+ /**
+ * Add a single variable (or remove if no = sign) to the current
+ * environment diff.
+ */
+ void PutEnv(const std::string& env);
+
+ /** Remove a single variable from the current environment diff. */
+ void UnPutEnv(const std::string& env);
+
+ /**
+ * Apply an ENVIRONMENT_MODIFICATION operation to this diff. Returns
+ * false and issues an error on parse failure.
+ */
+ bool ParseOperation(const std::string& envmod);
+
+ /**
+ * Apply this diff to the actual environment, optionally writing out the
+ * modifications to a CTest-compatible measurement stream.
+ */
+ void ApplyToCurrentEnv(std::ostringstream* measurement = nullptr);
+
+ private:
+ std::map<std::string, cm::optional<std::string>> diff;
+ };
+
/** Helper class to save and restore the environment.
Instantiate this class as an automatic variable on
the stack. Its constructor saves a copy of the current
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index cbe5d7d..25ff3bf 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -272,6 +272,8 @@ public:
cmListFileBacktrace Backtrace;
FileSetType HeadersFileSets;
+ FileSetType CxxModulesFileSets;
+ FileSetType CxxModuleHeadersFileSets;
cmTargetInternals();
@@ -293,6 +295,12 @@ public:
cm::string_view fileSetType) const;
cmValue GetFileSetPaths(cmTarget const* self, std::string const& fileSetName,
cm::string_view fileSetType) const;
+
+ cmListFileBacktrace GetBacktrace(
+ cm::optional<cmListFileBacktrace> const& bt) const
+ {
+ return bt ? *bt : this->Makefile->GetBacktrace();
+ }
};
cmTargetInternals::cmTargetInternals()
@@ -301,6 +309,19 @@ cmTargetInternals::cmTargetInternals()
"The default header set"_s, "Header set"_s,
FileSetEntries("HEADER_SETS"_s),
FileSetEntries("INTERFACE_HEADER_SETS"_s))
+ , CxxModulesFileSets("CXX_MODULES"_s, "CXX_MODULE_DIRS"_s,
+ "CXX_MODULE_SET"_s, "CXX_MODULE_DIRS_"_s,
+ "CXX_MODULE_SET_"_s, "C++ module"_s,
+ "The default C++ module set"_s, "C++ module set"_s,
+ FileSetEntries("CXX_MODULE_SETS"_s),
+ FileSetEntries("INTERFACE_CXX_MODULE_SETS"_s))
+ , CxxModuleHeadersFileSets(
+ "CXX_MODULE_HEADER_UNITS"_s, "CXX_MODULE_HEADER_UNIT_DIRS"_s,
+ "CXX_MODULE_HEADER_UNIT_SET"_s, "CXX_MODULE_HEADER_UNIT_DIRS_"_s,
+ "CXX_MODULE_HEADER_UNIT_SET_"_s, "C++ module header"_s,
+ "The default C++ module header set"_s, "C++ module header set"_s,
+ FileSetEntries("CXX_MODULE_HEADER_UNIT_SETS"_s),
+ FileSetEntries("INTERFACE_CXX_MODULE_HEADER_UNIT_SETS"_s))
{
}
@@ -605,12 +626,16 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("XCODE_SCHEME_THREAD_SANITIZER_STOP");
initProp("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER");
initProp("XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP");
+ initProp("XCODE_SCHEME_LAUNCH_CONFIGURATION");
+ initProp("XCODE_SCHEME_ENABLE_GPU_API_VALIDATION");
+ initProp("XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION");
initProp("XCODE_SCHEME_WORKING_DIRECTORY");
initProp("XCODE_SCHEME_DISABLE_MAIN_THREAD_CHECKER");
initProp("XCODE_SCHEME_MAIN_THREAD_CHECKER_STOP");
initProp("XCODE_SCHEME_MALLOC_SCRIBBLE");
initProp("XCODE_SCHEME_MALLOC_GUARD_EDGES");
initProp("XCODE_SCHEME_GUARD_MALLOC");
+ initProp("XCODE_SCHEME_LAUNCH_MODE");
initProp("XCODE_SCHEME_ZOMBIE_OBJECTS");
initProp("XCODE_SCHEME_MALLOC_STACK");
initProp("XCODE_SCHEME_DYNAMIC_LINKER_API_USAGE");
@@ -760,6 +785,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
}
}
+ if (this->IsImported()) {
+ this->SetProperty("SYSTEM", "ON");
+ }
+
for (auto const& prop : mf->GetState()->GetPropertyDefinitions().GetMap()) {
if (prop.first.second == cmProperty::TARGET &&
!prop.second.GetInitializeFromVariable().empty()) {
@@ -1223,7 +1252,8 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, std::string const& lib,
? targetNameGenex(lib)
: lib;
this->AppendProperty("LINK_LIBRARIES",
- this->GetDebugGeneratorExpressions(libName, llt));
+ this->GetDebugGeneratorExpressions(libName, llt),
+ mf.GetBacktrace());
}
if (cmGeneratorExpression::Find(lib) != std::string::npos ||
@@ -1367,11 +1397,32 @@ cmBTStringRange cmTarget::GetHeaderSetsEntries() const
return cmMakeRange(this->impl->HeadersFileSets.SelfEntries.Entries);
}
+cmBTStringRange cmTarget::GetCxxModuleSetsEntries() const
+{
+ return cmMakeRange(this->impl->CxxModulesFileSets.SelfEntries.Entries);
+}
+
+cmBTStringRange cmTarget::GetCxxModuleHeaderSetsEntries() const
+{
+ return cmMakeRange(this->impl->CxxModuleHeadersFileSets.SelfEntries.Entries);
+}
+
cmBTStringRange cmTarget::GetInterfaceHeaderSetsEntries() const
{
return cmMakeRange(this->impl->HeadersFileSets.InterfaceEntries.Entries);
}
+cmBTStringRange cmTarget::GetInterfaceCxxModuleSetsEntries() const
+{
+ return cmMakeRange(this->impl->CxxModulesFileSets.InterfaceEntries.Entries);
+}
+
+cmBTStringRange cmTarget::GetInterfaceCxxModuleHeaderSetsEntries() const
+{
+ return cmMakeRange(
+ this->impl->CxxModuleHeadersFileSets.InterfaceEntries.Entries);
+}
+
namespace {
#define MAKE_PROP(PROP) const std::string prop##PROP = #PROP
MAKE_PROP(C_STANDARD);
@@ -1631,13 +1682,21 @@ void cmTarget::StoreProperty(const std::string& prop, ValueType value)
} else if (this->impl->HeadersFileSets.WriteProperties(
this, this->impl.get(), prop, value, true)) {
/* Handled in the `if` condition. */
+ } else if (this->impl->CxxModulesFileSets.WriteProperties(
+ this, this->impl.get(), prop, value, true)) {
+ /* Handled in the `if` condition. */
+ } else if (this->impl->CxxModuleHeadersFileSets.WriteProperties(
+ this, this->impl.get(), prop, value, true)) {
+ /* Handled in the `if` condition. */
} else {
this->impl->Properties.SetProperty(prop, value);
}
}
void cmTarget::AppendProperty(const std::string& prop,
- const std::string& value, bool asString)
+ const std::string& value,
+ cm::optional<cmListFileBacktrace> const& bt,
+ bool asString)
{
if (prop == "NAME") {
this->impl->Makefile->IssueMessage(MessageType::FATAL_ERROR,
@@ -1668,32 +1727,32 @@ void cmTarget::AppendProperty(const std::string& prop,
}
if (prop == "INCLUDE_DIRECTORIES") {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->IncludeDirectoriesEntries.emplace_back(value, lfbt);
}
} else if (prop == "COMPILE_OPTIONS") {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->CompileOptionsEntries.emplace_back(value, lfbt);
}
} else if (prop == "COMPILE_FEATURES") {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->CompileFeaturesEntries.emplace_back(value, lfbt);
}
} else if (prop == "COMPILE_DEFINITIONS") {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->CompileDefinitionsEntries.emplace_back(value, lfbt);
}
} else if (prop == "LINK_OPTIONS") {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->LinkOptionsEntries.emplace_back(value, lfbt);
}
} else if (prop == "LINK_DIRECTORIES") {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->LinkDirectoriesEntries.emplace_back(value, lfbt);
}
} else if (prop == "PRECOMPILE_HEADERS") {
@@ -1706,32 +1765,32 @@ void cmTarget::AppendProperty(const std::string& prop,
return;
}
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->PrecompileHeadersEntries.emplace_back(value, lfbt);
}
} else if (prop == "LINK_LIBRARIES") {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->LinkImplementationPropertyEntries.emplace_back(value, lfbt);
}
} else if (prop == propINTERFACE_LINK_LIBRARIES) {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->LinkInterfacePropertyEntries.emplace_back(value, lfbt);
}
} else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT) {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->LinkInterfaceDirectPropertyEntries.emplace_back(value, lfbt);
}
} else if (prop == propINTERFACE_LINK_LIBRARIES_DIRECT_EXCLUDE) {
if (!value.empty()) {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->LinkInterfaceDirectExcludePropertyEntries.emplace_back(value,
lfbt);
}
} else if (prop == "SOURCES") {
- cmListFileBacktrace lfbt = this->impl->Makefile->GetBacktrace();
+ cmListFileBacktrace lfbt = this->impl->GetBacktrace(bt);
this->impl->SourceEntries.emplace_back(value, lfbt);
} else if (cmHasLiteralPrefix(prop, "IMPORTED_LIBNAME")) {
this->impl->Makefile->IssueMessage(
@@ -1742,6 +1801,13 @@ void cmTarget::AppendProperty(const std::string& prop,
this->impl->Makefile->IssueMessage(
MessageType::FATAL_ERROR, prop + " property may not be appended.");
} else if (this->impl->HeadersFileSets.WriteProperties(
+ this, this->impl.get(), prop, value,
+ false)) { // NOLINT(bugprone-branch-clone)
+ /* Handled in the `if` condition. */
+ } else if (this->impl->CxxModulesFileSets.WriteProperties(
+ this, this->impl.get(), prop, value, false)) {
+ /* Handled in the `if` condition. */
+ } else if (this->impl->CxxModuleHeadersFileSets.WriteProperties(
this, this->impl.get(), prop, value, false)) {
/* Handled in the `if` condition. */
} else {
@@ -2307,6 +2373,17 @@ cmValue cmTarget::GetProperty(const std::string& prop) const
if (headers.first) {
return headers.second;
}
+ auto cxx_modules = this->impl->CxxModulesFileSets.ReadProperties(
+ this, this->impl.get(), prop);
+ if (cxx_modules.first) {
+ return cxx_modules.second;
+ }
+ auto cxx_module_headers =
+ this->impl->CxxModuleHeadersFileSets.ReadProperties(
+ this, this->impl.get(), prop);
+ if (cxx_module_headers.first) {
+ return cxx_module_headers.second;
+ }
}
cmValue retVal = this->impl->Properties.GetPropertyValue(prop);
@@ -2584,6 +2661,11 @@ std::pair<cmFileSet*, bool> cmTarget::GetOrCreateFileSet(
auto bt = this->impl->Makefile->GetBacktrace();
if (type == this->impl->HeadersFileSets.TypeName) {
this->impl->HeadersFileSets.AddFileSet(name, vis, std::move(bt));
+ } else if (type == this->impl->CxxModulesFileSets.TypeName) {
+ this->impl->CxxModulesFileSets.AddFileSet(name, vis, std::move(bt));
+ } else if (type == this->impl->CxxModuleHeadersFileSets.TypeName) {
+ this->impl->CxxModuleHeadersFileSets.AddFileSet(name, vis,
+ std::move(bt));
}
}
return std::make_pair(&result.first->second, result.second);
@@ -2594,6 +2676,12 @@ std::string cmTarget::GetFileSetsPropertyName(const std::string& type)
if (type == "HEADERS") {
return "HEADER_SETS";
}
+ if (type == "CXX_MODULES") {
+ return "CXX_MODULE_SETS";
+ }
+ if (type == "CXX_MODULE_HEADER_UNITS") {
+ return "CXX_MODULE_HEADER_UNIT_SETS";
+ }
return "";
}
@@ -2602,6 +2690,12 @@ std::string cmTarget::GetInterfaceFileSetsPropertyName(const std::string& type)
if (type == "HEADERS") {
return "INTERFACE_HEADER_SETS";
}
+ if (type == "CXX_MODULES") {
+ return "INTERFACE_CXX_MODULE_SETS";
+ }
+ if (type == "CXX_MODULE_HEADER_UNITS") {
+ return "INTERFACE_CXX_MODULE_HEADER_UNIT_SETS";
+ }
return "";
}
@@ -2629,6 +2723,8 @@ std::vector<std::string> cmTarget::GetAllInterfaceFileSets() const
};
appendEntries(this->impl->HeadersFileSets.InterfaceEntries.Entries);
+ appendEntries(this->impl->CxxModulesFileSets.InterfaceEntries.Entries);
+ appendEntries(this->impl->CxxModuleHeadersFileSets.InterfaceEntries.Entries);
return result;
}
diff --git a/Source/cmTarget.h b/Source/cmTarget.h
index 467c4da..38bd036 100644
--- a/Source/cmTarget.h
+++ b/Source/cmTarget.h
@@ -185,8 +185,10 @@ public:
{
this->SetProperty(prop, cmValue(value));
}
- void AppendProperty(const std::string& prop, const std::string& value,
- bool asString = false);
+ void AppendProperty(
+ const std::string& prop, const std::string& value,
+ cm::optional<cmListFileBacktrace> const& bt = cm::nullopt,
+ bool asString = false);
//! Might return a nullptr if the property is not set or invalid
cmValue GetProperty(const std::string& prop) const;
//! Always returns a valid pointer
@@ -281,8 +283,12 @@ public:
cmBTStringRange GetLinkInterfaceDirectExcludeEntries() const;
cmBTStringRange GetHeaderSetsEntries() const;
+ cmBTStringRange GetCxxModuleSetsEntries() const;
+ cmBTStringRange GetCxxModuleHeaderSetsEntries() const;
cmBTStringRange GetInterfaceHeaderSetsEntries() const;
+ cmBTStringRange GetInterfaceCxxModuleSetsEntries() const;
+ cmBTStringRange GetInterfaceCxxModuleHeaderSetsEntries() const;
std::string ImportedGetFullPath(const std::string& config,
cmStateEnums::ArtifactType artifact) const;
diff --git a/Source/cmTargetCompileDefinitionsCommand.cxx b/Source/cmTargetCompileDefinitionsCommand.cxx
index b56b245..268bfac 100644
--- a/Source/cmTargetCompileDefinitionsCommand.cxx
+++ b/Source/cmTargetCompileDefinitionsCommand.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTargetCompileDefinitionsCommand.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
@@ -28,7 +29,8 @@ private:
const std::vector<std::string>& content,
bool /*prepend*/, bool /*system*/) override
{
- tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content));
+ tgt->AppendProperty("COMPILE_DEFINITIONS", this->Join(content),
+ this->Makefile->GetBacktrace());
return true; // Successfully handled.
}
diff --git a/Source/cmTargetExport.h b/Source/cmTargetExport.h
index 885ac74..1cef888 100644
--- a/Source/cmTargetExport.h
+++ b/Source/cmTargetExport.h
@@ -8,6 +8,7 @@
class cmFileSet;
class cmGeneratorTarget;
+class cmInstallCxxModuleBmiGenerator;
class cmInstallFileSetGenerator;
class cmInstallFilesGenerator;
class cmInstallTargetGenerator;
@@ -32,6 +33,7 @@ public:
cmInstallTargetGenerator* BundleGenerator;
cmInstallFilesGenerator* HeaderGenerator;
std::map<cmFileSet*, cmInstallFileSetGenerator*> FileSetGenerators;
+ cmInstallCxxModuleBmiGenerator* CxxModuleBmiGenerator;
///@}
bool NamelinkOnly = false;
diff --git a/Source/cmTargetIncludeDirectoriesCommand.cxx b/Source/cmTargetIncludeDirectoriesCommand.cxx
index b4b4319..cb83873 100644
--- a/Source/cmTargetIncludeDirectoriesCommand.cxx
+++ b/Source/cmTargetIncludeDirectoriesCommand.cxx
@@ -88,7 +88,8 @@ void TargetIncludeDirectoriesImpl::HandleInterfaceContent(
system);
if (system) {
std::string joined = this->Join(content);
- tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined);
+ tgt->AppendProperty("INTERFACE_SYSTEM_INCLUDE_DIRECTORIES", joined,
+ this->Makefile->GetBacktrace());
}
}
diff --git a/Source/cmTargetLinkLibrariesCommand.cxx b/Source/cmTargetLinkLibrariesCommand.cxx
index af870da..0b123b2 100644
--- a/Source/cmTargetLinkLibrariesCommand.cxx
+++ b/Source/cmTargetLinkLibrariesCommand.cxx
@@ -622,7 +622,7 @@ bool TLL::HandleLibrary(ProcessingState currentProcessingState,
void TLL::AppendProperty(std::string const& prop, std::string const& value)
{
this->AffectsProperty(prop);
- this->Target->AppendProperty(prop, value);
+ this->Target->AppendProperty(prop, value, this->Makefile.GetBacktrace());
}
void TLL::AffectsProperty(std::string const& prop)
@@ -633,14 +633,16 @@ void TLL::AffectsProperty(std::string const& prop)
// Add a wrapper to the expression to tell LookupLinkItem to look up
// names in the caller's directory.
if (this->Props.insert(prop).second) {
- this->Target->AppendProperty(prop, this->DirectoryId);
+ this->Target->AppendProperty(prop, this->DirectoryId,
+ this->Makefile.GetBacktrace());
}
}
TLL::~TLL()
{
for (std::string const& prop : this->Props) {
- this->Target->AppendProperty(prop, CMAKE_DIRECTORY_ID_SEP);
+ this->Target->AppendProperty(prop, CMAKE_DIRECTORY_ID_SEP,
+ this->Makefile.GetBacktrace());
}
}
diff --git a/Source/cmTargetPrecompileHeadersCommand.cxx b/Source/cmTargetPrecompileHeadersCommand.cxx
index a5066cc..4dd158d 100644
--- a/Source/cmTargetPrecompileHeadersCommand.cxx
+++ b/Source/cmTargetPrecompileHeadersCommand.cxx
@@ -5,6 +5,7 @@
#include <utility>
#include "cmGeneratorExpression.h"
+#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmStringAlgorithms.h"
@@ -48,7 +49,8 @@ private:
{
std::string const& base = this->Makefile->GetCurrentSourceDirectory();
tgt->AppendProperty("PRECOMPILE_HEADERS",
- this->Join(ConvertToAbsoluteContent(content, base)));
+ this->Join(ConvertToAbsoluteContent(content, base)),
+ this->Makefile->GetBacktrace());
return true;
}
diff --git a/Source/cmTargetSourcesCommand.cxx b/Source/cmTargetSourcesCommand.cxx
index b1367e1..53e25b5 100644
--- a/Source/cmTargetSourcesCommand.cxx
+++ b/Source/cmTargetSourcesCommand.cxx
@@ -9,6 +9,8 @@
#include <cmext/string_view>
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
+#include "cmExperimental.h"
#include "cmFileSet.h"
#include "cmGeneratorExpression.h"
#include "cmListFileCache.h"
@@ -27,8 +29,8 @@ struct FileSetArgs
{
std::string Type;
std::string FileSet;
- std::vector<std::string> BaseDirs;
- std::vector<std::string> Files;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> BaseDirs;
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> Files;
};
auto const FileSetArgsParser = cmArgumentParser<FileSetArgs>()
@@ -77,7 +79,8 @@ private:
{
tgt->AppendProperty("SOURCES",
this->Join(this->ConvertToAbsoluteContent(
- tgt, content, IsInterface::No, CheckCMP0076::Yes)));
+ tgt, content, IsInterface::No, CheckCMP0076::Yes)),
+ this->Makefile->GetBacktrace());
return true; // Successfully handled.
}
@@ -196,7 +199,7 @@ std::vector<std::string> TargetSourcesImpl::ConvertToAbsoluteContent(
bool TargetSourcesImpl::HandleFileSetMode(
const std::string& scope, const std::vector<std::string>& content)
{
- auto args = FileSetsArgsParser.Parse(content);
+ auto args = FileSetsArgsParser.Parse(content, /*unparsedArguments=*/nullptr);
for (auto& argList : args.FileSets) {
argList.emplace(argList.begin(), "FILE_SET"_s);
@@ -256,9 +259,31 @@ bool TargetSourcesImpl::HandleOneFileSet(
this->SetError("Must specify a TYPE when creating file set");
return false;
}
- if (type != "HEADERS"_s) {
- this->SetError("File set TYPE may only be \"HEADERS\"");
- return false;
+ bool const supportCxx20FileSetTypes = cmExperimental::HasSupportEnabled(
+ *this->Makefile, cmExperimental::Feature::CxxModuleCMakeApi);
+
+ if (supportCxx20FileSetTypes) {
+ if (type != "HEADERS"_s && type != "CXX_MODULES"_s &&
+ type != "CXX_MODULE_HEADER_UNITS"_s) {
+ this->SetError(
+ R"(File set TYPE may only be "HEADERS", "CXX_MODULES", or "CXX_MODULE_HEADER_UNITS")");
+ return false;
+ }
+
+ if (cmFileSetVisibilityIsForInterface(visibility) &&
+ !cmFileSetVisibilityIsForSelf(visibility) &&
+ !this->Target->IsImported()) {
+ if (type == "CXX_MODULES"_s || type == "CXX_MODULE_HEADER_UNITS"_s) {
+ this->SetError(
+ R"(File set TYPEs "CXX_MODULES" and "CXX_MODULE_HEADER_UNITS" may not have "INTERFACE" visibility)");
+ return false;
+ }
+ }
+ } else {
+ if (type != "HEADERS"_s) {
+ this->SetError("File set TYPE may only be \"HEADERS\"");
+ return false;
+ }
}
if (args.BaseDirs.empty()) {
@@ -294,17 +319,19 @@ bool TargetSourcesImpl::HandleOneFileSet(
if (!baseDirectories.empty()) {
fileSet.first->AddDirectoryEntry(
BT<std::string>(baseDirectories, this->Makefile->GetBacktrace()));
- if (type == "HEADERS"_s) {
+ if (type == "HEADERS"_s || type == "CXX_MODULE_HEADER_UNITS"_s) {
for (auto const& dir : cmExpandedList(baseDirectories)) {
auto interfaceDirectoriesGenex =
cmStrCat("$<BUILD_INTERFACE:", dir, ">");
if (cmFileSetVisibilityIsForSelf(visibility)) {
this->Target->AppendProperty("INCLUDE_DIRECTORIES",
- interfaceDirectoriesGenex);
+ interfaceDirectoriesGenex,
+ this->Makefile->GetBacktrace());
}
if (cmFileSetVisibilityIsForInterface(visibility)) {
this->Target->AppendProperty("INTERFACE_INCLUDE_DIRECTORIES",
- interfaceDirectoriesGenex);
+ interfaceDirectoriesGenex,
+ this->Makefile->GetBacktrace());
}
}
}
diff --git a/Source/cmTryCompileCommand.cxx b/Source/cmTryCompileCommand.cxx
index 130c228..b59c225 100644
--- a/Source/cmTryCompileCommand.cxx
+++ b/Source/cmTryCompileCommand.cxx
@@ -2,34 +2,66 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmTryCompileCommand.h"
+#include "cmCoreTryCompile.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
+#include "cmRange.h"
+#include "cmState.h"
+#include "cmStateTypes.h"
+#include "cmStringAlgorithms.h"
+#include "cmValue.h"
#include "cmake.h"
-class cmExecutionStatus;
-
-// cmTryCompileCommand
-bool cmTryCompileCommand::InitialPass(std::vector<std::string> const& argv,
- cmExecutionStatus&)
+bool cmTryCompileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
{
- if (argv.size() < 3) {
+ if (args.size() < 3) {
return false;
}
- if (this->Makefile->GetCMakeInstance()->GetWorkingMode() ==
- cmake::FIND_PACKAGE_MODE) {
- this->Makefile->IssueMessage(
+ cmMakefile& mf = status.GetMakefile();
+
+ if (mf.GetCMakeInstance()->GetWorkingMode() == cmake::FIND_PACKAGE_MODE) {
+ mf.IssueMessage(
MessageType::FATAL_ERROR,
"The try_compile() command is not supported in --find-package mode.");
return false;
}
- this->TryCompileCode(argv, false);
+ cmStateEnums::TargetType targetType = cmStateEnums::EXECUTABLE;
+ cmValue tt = mf.GetDefinition("CMAKE_TRY_COMPILE_TARGET_TYPE");
+ if (cmNonempty(tt)) {
+ if (*tt == cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE)) {
+ targetType = cmStateEnums::EXECUTABLE;
+ } else if (*tt ==
+ cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY)) {
+ targetType = cmStateEnums::STATIC_LIBRARY;
+ } else {
+ mf.IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("Invalid value '", *tt,
+ "' for CMAKE_TRY_COMPILE_TARGET_TYPE. Only '",
+ cmState::GetTargetTypeName(cmStateEnums::EXECUTABLE),
+ "' and '",
+ cmState::GetTargetTypeName(cmStateEnums::STATIC_LIBRARY),
+ "' are allowed."));
+ return false;
+ }
+ }
+
+ cmCoreTryCompile tc(&mf);
+ cmCoreTryCompile::Arguments arguments =
+ tc.ParseArgs(cmMakeRange(args), false);
+ if (!arguments) {
+ return true;
+ }
+ tc.TryCompileCode(arguments, targetType);
// if They specified clean then we clean up what we can
- if (this->SrcFileSignature) {
- if (!this->Makefile->GetCMakeInstance()->GetDebugTryCompile()) {
- this->CleanupFiles(this->BinaryDirectory);
+ if (tc.SrcFileSignature) {
+ if (!mf.GetCMakeInstance()->GetDebugTryCompile()) {
+ tc.CleanupFiles(tc.BinaryDirectory);
}
}
return true;
diff --git a/Source/cmTryCompileCommand.h b/Source/cmTryCompileCommand.h
index d8cc16e..6a3430b 100644
--- a/Source/cmTryCompileCommand.h
+++ b/Source/cmTryCompileCommand.h
@@ -7,33 +7,7 @@
#include <string>
#include <vector>
-#include <cm/memory>
-
-#include "cmCommand.h"
-#include "cmCoreTryCompile.h"
-
class cmExecutionStatus;
-/** \class cmTryCompileCommand
- * \brief Specifies where to install some files
- *
- * cmTryCompileCommand is used to test if source code can be compiled
- */
-class cmTryCompileCommand : public cmCoreTryCompile
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmTryCompileCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-};
+bool cmTryCompileCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
diff --git a/Source/cmTryRunCommand.cxx b/Source/cmTryRunCommand.cxx
index c82ac64..7a29521 100644
--- a/Source/cmTryRunCommand.cxx
+++ b/Source/cmTryRunCommand.cxx
@@ -4,9 +4,14 @@
#include <cstdio>
+#include <cm/optional>
+
#include "cmsys/FStream.hxx"
+#include "cmArgumentParserTypes.h"
+#include "cmCoreTryCompile.h"
#include "cmDuration.h"
+#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmRange.h"
@@ -17,157 +22,155 @@
#include "cmValue.h"
#include "cmake.h"
-class cmExecutionStatus;
+namespace {
-// cmTryRunCommand
-bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
- cmExecutionStatus&)
+class TryRunCommandImpl : public cmCoreTryCompile
{
- if (argv.size() < 4) {
- return false;
+public:
+ TryRunCommandImpl(cmMakefile* mf)
+ : cmCoreTryCompile(mf)
+ {
}
- if (this->Makefile->GetCMakeInstance()->GetWorkingMode() ==
- cmake::FIND_PACKAGE_MODE) {
- this->Makefile->IssueMessage(
- MessageType::FATAL_ERROR,
- "The try_run() command is not supported in --find-package mode.");
- return false;
- }
+ bool TryRunCode(std::vector<std::string> const& args);
- // build an arg list for TryCompile and extract the runArgs,
- std::vector<std::string> tryCompile;
-
- this->CompileResultVariable.clear();
- this->RunResultVariable.clear();
- this->OutputVariable.clear();
- this->RunOutputVariable.clear();
- this->CompileOutputVariable.clear();
-
- std::string runArgs;
- unsigned int i;
- for (i = 1; i < argv.size(); ++i) {
- if (argv[i] == "ARGS") {
- ++i;
- while (i < argv.size() && argv[i] != "COMPILE_DEFINITIONS" &&
- argv[i] != "CMAKE_FLAGS" && argv[i] != "LINK_OPTIONS" &&
- argv[i] != "LINK_LIBRARIES") {
- runArgs += " ";
- runArgs += argv[i];
- ++i;
- }
- if (i < argv.size()) {
- tryCompile.push_back(argv[i]);
- }
- } else {
- if (argv[i] == "OUTPUT_VARIABLE") {
- if (argv.size() <= (i + 1)) {
- cmSystemTools::Error(
- "OUTPUT_VARIABLE specified but there is no variable");
- return false;
- }
- i++;
- this->OutputVariable = argv[i];
- } else if (argv[i] == "RUN_OUTPUT_VARIABLE") {
- if (argv.size() <= (i + 1)) {
- cmSystemTools::Error(
- "RUN_OUTPUT_VARIABLE specified but there is no variable");
- return false;
- }
- i++;
- this->RunOutputVariable = argv[i];
- } else if (argv[i] == "COMPILE_OUTPUT_VARIABLE") {
- if (argv.size() <= (i + 1)) {
- cmSystemTools::Error(
- "COMPILE_OUTPUT_VARIABLE specified but there is no variable");
- return false;
- }
- i++;
- this->CompileOutputVariable = argv[i];
- } else if (argv[i] == "WORKING_DIRECTORY") {
- if (argv.size() <= (i + 1)) {
- cmSystemTools::Error(
- "WORKING_DIRECTORY specified but there is no variable");
- return false;
- }
- i++;
- this->WorkingDirectory = argv[i];
- } else {
- tryCompile.push_back(argv[i]);
- }
- }
+ void RunExecutable(const std::string& runArgs,
+ cm::optional<std::string> const& workDir,
+ std::string* runOutputContents,
+ std::string* runOutputStdOutContents,
+ std::string* runOutputStdErrContents);
+ void DoNotRunExecutable(const std::string& runArgs,
+ const std::string& srcFile,
+ std::string const& compileResultVariable,
+ std::string* runOutputContents,
+ std::string* runOutputStdOutContents,
+ std::string* runOutputStdErrContents);
+
+ std::string RunResultVariable;
+};
+
+bool TryRunCommandImpl::TryRunCode(std::vector<std::string> const& argv)
+{
+ this->RunResultVariable = argv[0];
+ cmCoreTryCompile::Arguments arguments =
+ this->ParseArgs(cmMakeRange(argv).advance(1), true);
+ if (!arguments) {
+ return true;
}
// although they could be used together, don't allow it, because
// using OUTPUT_VARIABLE makes crosscompiling harder
- if (!this->OutputVariable.empty() &&
- (!this->RunOutputVariable.empty() ||
- !this->CompileOutputVariable.empty())) {
+ if (arguments.OutputVariable &&
+ (arguments.CompileOutputVariable || arguments.RunOutputVariable ||
+ arguments.RunOutputStdOutVariable ||
+ arguments.RunOutputStdErrVariable)) {
cmSystemTools::Error(
"You cannot use OUTPUT_VARIABLE together with COMPILE_OUTPUT_VARIABLE "
- "or RUN_OUTPUT_VARIABLE. Please use only COMPILE_OUTPUT_VARIABLE and/or "
- "RUN_OUTPUT_VARIABLE.");
+ ", RUN_OUTPUT_VARIABLE, RUN_OUTPUT_STDOUT_VARIABLE or "
+ "RUN_OUTPUT_STDERR_VARIABLE. "
+ "Please use only COMPILE_OUTPUT_VARIABLE, RUN_OUTPUT_VARIABLE, "
+ "RUN_OUTPUT_STDOUT_VARIABLE "
+ "and/or RUN_OUTPUT_STDERR_VARIABLE.");
return false;
}
- if (!this->WorkingDirectory.empty()) {
- if (!cmSystemTools::MakeDirectory(this->WorkingDirectory)) {
+ if ((arguments.RunOutputStdOutVariable ||
+ arguments.RunOutputStdErrVariable) &&
+ arguments.RunOutputVariable) {
+ cmSystemTools::Error(
+ "You cannot use RUN_OUTPUT_STDOUT_VARIABLE or "
+ "RUN_OUTPUT_STDERR_VARIABLE together "
+ "with RUN_OUTPUT_VARIABLE. Please use only COMPILE_OUTPUT_VARIABLE or "
+ "RUN_OUTPUT_STDOUT_VARIABLE and/or RUN_OUTPUT_STDERR_VARIABLE.");
+ return false;
+ }
+
+ if (arguments.RunWorkingDirectory) {
+ if (!cmSystemTools::MakeDirectory(*arguments.RunWorkingDirectory)) {
cmSystemTools::Error(cmStrCat("Error creating working directory \"",
- this->WorkingDirectory, "\"."));
+ *arguments.RunWorkingDirectory, "\"."));
return false;
}
}
bool captureRunOutput = false;
- if (!this->OutputVariable.empty()) {
+ bool captureRunOutputStdOutErr = false;
+ if (arguments.OutputVariable) {
captureRunOutput = true;
- tryCompile.emplace_back("OUTPUT_VARIABLE");
- tryCompile.push_back(this->OutputVariable);
- }
- if (!this->CompileOutputVariable.empty()) {
- tryCompile.emplace_back("OUTPUT_VARIABLE");
- tryCompile.push_back(this->CompileOutputVariable);
+ } else if (arguments.CompileOutputVariable) {
+ arguments.OutputVariable = arguments.CompileOutputVariable;
}
- if (!this->RunOutputVariable.empty()) {
+ if (arguments.RunOutputStdOutVariable || arguments.RunOutputStdErrVariable) {
+ captureRunOutputStdOutErr = true;
+ } else if (arguments.RunOutputVariable) {
captureRunOutput = true;
}
- this->RunResultVariable = argv[0];
- this->CompileResultVariable = argv[1];
-
// do the try compile
- int res = this->TryCompileCode(tryCompile, true);
+ bool compiled = this->TryCompileCode(arguments, cmStateEnums::EXECUTABLE);
// now try running the command if it compiled
- if (!res) {
+ if (compiled) {
if (this->OutputFile.empty()) {
cmSystemTools::Error(this->FindErrorMessage);
} else {
+ std::string runArgs;
+ if (arguments.RunArgs) {
+ runArgs = cmStrCat(" ", cmJoin(*arguments.RunArgs, " "));
+ }
+
// "run" it and capture the output
std::string runOutputContents;
+ std::string runOutputStdOutContents;
+ std::string runOutputStdErrContents;
if (this->Makefile->IsOn("CMAKE_CROSSCOMPILING") &&
!this->Makefile->IsDefinitionSet("CMAKE_CROSSCOMPILING_EMULATOR")) {
this->DoNotRunExecutable(
- runArgs, argv[3], captureRunOutput ? &runOutputContents : nullptr);
+ runArgs, *arguments.SourceDirectoryOrFile,
+ *arguments.CompileResultVariable,
+ captureRunOutput ? &runOutputContents : nullptr,
+ captureRunOutputStdOutErr && arguments.RunOutputStdOutVariable
+ ? &runOutputStdOutContents
+ : nullptr,
+ captureRunOutputStdOutErr && arguments.RunOutputStdErrVariable
+ ? &runOutputStdErrContents
+ : nullptr);
} else {
- this->RunExecutable(runArgs, &runOutputContents);
+ this->RunExecutable(
+ runArgs, arguments.RunWorkingDirectory,
+ captureRunOutput ? &runOutputContents : nullptr,
+ captureRunOutputStdOutErr && arguments.RunOutputStdOutVariable
+ ? &runOutputStdOutContents
+ : nullptr,
+ captureRunOutputStdOutErr && arguments.RunOutputStdErrVariable
+ ? &runOutputStdErrContents
+ : nullptr);
}
// now put the output into the variables
- if (!this->RunOutputVariable.empty()) {
- this->Makefile->AddDefinition(this->RunOutputVariable,
+ if (arguments.RunOutputVariable) {
+ this->Makefile->AddDefinition(*arguments.RunOutputVariable,
runOutputContents);
}
+ if (arguments.RunOutputStdOutVariable) {
+ this->Makefile->AddDefinition(*arguments.RunOutputStdOutVariable,
+ runOutputStdOutContents);
+ }
+ if (arguments.RunOutputStdErrVariable) {
+ this->Makefile->AddDefinition(*arguments.RunOutputStdErrVariable,
+ runOutputStdErrContents);
+ }
- if (!this->OutputVariable.empty()) {
+ if (arguments.OutputVariable && !arguments.CompileOutputVariable) {
// if the TryCompileCore saved output in this outputVariable then
// prepend that output to this output
cmValue compileOutput =
- this->Makefile->GetDefinition(this->OutputVariable);
+ this->Makefile->GetDefinition(*arguments.OutputVariable);
if (compileOutput) {
runOutputContents = *compileOutput + runOutputContents;
}
- this->Makefile->AddDefinition(this->OutputVariable, runOutputContents);
+ this->Makefile->AddDefinition(*arguments.OutputVariable,
+ runOutputContents);
}
}
}
@@ -179,8 +182,10 @@ bool cmTryRunCommand::InitialPass(std::vector<std::string> const& argv,
return true;
}
-void cmTryRunCommand::RunExecutable(const std::string& runArgs,
- std::string* out)
+void TryRunCommandImpl::RunExecutable(const std::string& runArgs,
+ cm::optional<std::string> const& workDir,
+ std::string* out, std::string* stdOut,
+ std::string* stdErr)
{
int retVal = -1;
@@ -204,9 +209,10 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
finalCommand += runArgs;
}
bool worked = cmSystemTools::RunSingleCommand(
- finalCommand, out, out, &retVal,
- this->WorkingDirectory.empty() ? nullptr : this->WorkingDirectory.c_str(),
- cmSystemTools::OUTPUT_NONE, cmDuration::zero());
+ finalCommand, stdOut || stdErr ? stdOut : out,
+ stdOut || stdErr ? stdErr : out, &retVal,
+ workDir ? workDir->c_str() : nullptr, cmSystemTools::OUTPUT_NONE,
+ cmDuration::zero());
// set the run var
char retChar[16];
const char* retStr;
@@ -225,9 +231,10 @@ void cmTryRunCommand::RunExecutable(const std::string& runArgs,
executable, two cache variables are created which will hold the results
the executable would have produced.
*/
-void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
- const std::string& srcFile,
- std::string* out)
+void TryRunCommandImpl::DoNotRunExecutable(
+ const std::string& runArgs, const std::string& srcFile,
+ std::string const& compileResultVariable, std::string* out,
+ std::string* stdOut, std::string* stdErr)
{
// copy the executable out of the CMakeFiles/ directory, so it is not
// removed at the end of try_run() and the user can run it manually
@@ -246,6 +253,10 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
std::string internalRunOutputName =
this->RunResultVariable + "__TRYRUN_OUTPUT";
+ std::string internalRunOutputStdOutName =
+ this->RunResultVariable + "__TRYRUN_OUTPUT_STDOUT";
+ std::string internalRunOutputStdErrName =
+ this->RunResultVariable + "__TRYRUN_OUTPUT_STDERR";
bool error = false;
if (!this->Makefile->GetDefinition(this->RunResultVariable)) {
@@ -269,7 +280,51 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
}
// is the output from the executable used ?
- if (out) {
+ if (stdOut || stdErr) {
+ if (!this->Makefile->GetDefinition(internalRunOutputStdOutName)) {
+ // if the variables doesn't exist, create it with a helpful error text
+ // and mark it as advanced
+ std::string comment = cmStrCat(
+ "Output of try_run(), contains the text, which the executable "
+ "would have printed on stdout on its target platform.\n",
+ detailsString);
+
+ this->Makefile->AddCacheDefinition(
+ internalRunOutputStdOutName, "PLEASE_FILL_OUT-NOTFOUND",
+ comment.c_str(), cmStateEnums::STRING);
+ cmState* state = this->Makefile->GetState();
+ cmValue existing =
+ state->GetCacheEntryValue(internalRunOutputStdOutName);
+ if (existing) {
+ state->SetCacheEntryProperty(internalRunOutputStdOutName, "ADVANCED",
+ "1");
+ }
+
+ error = true;
+ }
+
+ if (!this->Makefile->GetDefinition(internalRunOutputStdErrName)) {
+ // if the variables doesn't exist, create it with a helpful error text
+ // and mark it as advanced
+ std::string comment = cmStrCat(
+ "Output of try_run(), contains the text, which the executable "
+ "would have printed on stderr on its target platform.\n",
+ detailsString);
+
+ this->Makefile->AddCacheDefinition(
+ internalRunOutputStdErrName, "PLEASE_FILL_OUT-NOTFOUND",
+ comment.c_str(), cmStateEnums::STRING);
+ cmState* state = this->Makefile->GetState();
+ cmValue existing =
+ state->GetCacheEntryValue(internalRunOutputStdErrName);
+ if (existing) {
+ state->SetCacheEntryProperty(internalRunOutputStdErrName, "ADVANCED",
+ "1");
+ }
+
+ error = true;
+ }
+ } else if (out) {
if (!this->Makefile->GetDefinition(internalRunOutputName)) {
// if the variables doesn't exist, create it with a helpful error text
// and mark it as advanced
@@ -317,7 +372,34 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
" to\n"
" the exit code (in many cases 0 for success), otherwise "
"enter \"FAILED_TO_RUN\".\n");
- if (out) {
+ if (stdOut || stdErr) {
+ if (stdOut) {
+ comment += internalRunOutputStdOutName;
+ comment +=
+ "\n contains the text the executable "
+ "would have printed on stdout.\n"
+ " If the executable would not have been able to run, set ";
+ comment += internalRunOutputStdOutName;
+ comment += " empty.\n"
+ " Otherwise check if the output is evaluated by the "
+ "calling CMake code. If so,\n"
+ " check what the source file would have printed when "
+ "called with the given arguments.\n";
+ }
+ if (stdErr) {
+ comment += internalRunOutputStdErrName;
+ comment +=
+ "\n contains the text the executable "
+ "would have printed on stderr.\n"
+ " If the executable would not have been able to run, set ";
+ comment += internalRunOutputStdErrName;
+ comment += " empty.\n"
+ " Otherwise check if the output is evaluated by the "
+ "calling CMake code. If so,\n"
+ " check what the source file would have printed when "
+ "called with the given arguments.\n";
+ }
+ } else if (out) {
comment += internalRunOutputName;
comment +=
"\n contains the text the executable "
@@ -330,8 +412,9 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
" check what the source file would have printed when "
"called with the given arguments.\n";
}
+
comment += "The ";
- comment += this->CompileResultVariable;
+ comment += compileResultVariable;
comment += " variable holds the build result for this try_run().\n\n"
"Source file : ";
comment += srcFile + "\n";
@@ -370,7 +453,35 @@ void cmTryRunCommand::DoNotRunExecutable(const std::string& runArgs,
return;
}
- if (out) {
+ if (stdOut || stdErr) {
+ if (stdOut) {
+ (*stdOut) = *this->Makefile->GetDefinition(internalRunOutputStdOutName);
+ }
+ if (stdErr) {
+ (*stdErr) = *this->Makefile->GetDefinition(internalRunOutputStdErrName);
+ }
+ } else if (out) {
(*out) = *this->Makefile->GetDefinition(internalRunOutputName);
}
}
+}
+
+bool cmTryRunCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status)
+{
+ if (args.size() < 4) {
+ return false;
+ }
+
+ cmMakefile& mf = status.GetMakefile();
+
+ if (mf.GetCMakeInstance()->GetWorkingMode() == cmake::FIND_PACKAGE_MODE) {
+ mf.IssueMessage(
+ MessageType::FATAL_ERROR,
+ "The try_run() command is not supported in --find-package mode.");
+ return false;
+ }
+
+ TryRunCommandImpl tr(&mf);
+ return tr.TryRunCode(args);
+}
diff --git a/Source/cmTryRunCommand.h b/Source/cmTryRunCommand.h
index d45acd8..38e3638 100644
--- a/Source/cmTryRunCommand.h
+++ b/Source/cmTryRunCommand.h
@@ -7,47 +7,7 @@
#include <string>
#include <vector>
-#include <cm/memory>
-
-#include "cmCommand.h"
-#include "cmCoreTryCompile.h"
-
class cmExecutionStatus;
-/** \class cmTryRunCommand
- * \brief Specifies where to install some files
- *
- * cmTryRunCommand is used to test if source code can be compiled
- */
-class cmTryRunCommand : public cmCoreTryCompile
-{
-public:
- /**
- * This is a virtual constructor for the command.
- */
- std::unique_ptr<cmCommand> Clone() override
- {
- return cm::make_unique<cmTryRunCommand>();
- }
-
- /**
- * This is called when the command is first encountered in
- * the CMakeLists.txt file.
- */
- bool InitialPass(std::vector<std::string> const& args,
- cmExecutionStatus& status) override;
-
-private:
- void RunExecutable(const std::string& runArgs,
- std::string* runOutputContents);
- void DoNotRunExecutable(const std::string& runArgs,
- const std::string& srcFile,
- std::string* runOutputContents);
-
- std::string CompileResultVariable;
- std::string RunResultVariable;
- std::string OutputVariable;
- std::string RunOutputVariable;
- std::string CompileOutputVariable;
- std::string WorkingDirectory;
-};
+bool cmTryRunCommand(std::vector<std::string> const& args,
+ cmExecutionStatus& status);
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 9f3d620..4c1fa01 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -354,6 +354,18 @@ std::ostream& cmVisualStudio10TargetGenerator::Elem::WriteString(
void cmVisualStudio10TargetGenerator::Generate()
{
+ for (std::string const& config : this->Configurations) {
+ this->GeneratorTarget->CheckCxxModuleStatus(config);
+ }
+
+ if (this->GeneratorTarget->HaveCxx20ModuleSources()) {
+ this->Makefile->IssueMessage(
+ MessageType::FATAL_ERROR,
+ cmStrCat("The \"", this->GeneratorTarget->GetName(),
+ "\" target contains C++ module sources which are not supported "
+ "by the generator"));
+ }
+
this->ProjectType = computeProjectType(this->GeneratorTarget);
this->Managed = this->ProjectType == VsProjectType::csproj;
const std::string ProjectFileExtension =
@@ -957,6 +969,10 @@ void cmVisualStudio10TargetGenerator::WriteSdkStyleProjectFile(
std::string outDir = this->GeneratorTarget->GetDirectory(config) + "/";
ConvertToWindowsSlash(outDir);
e1.Element("OutputPath", outDir);
+
+ Options& o = *(this->ClOptions[config]);
+ OptionsHelper oh(o, e1);
+ oh.OutputFlagMap();
}
this->WriteDotNetDocumentationFile(e0);
@@ -1507,6 +1523,10 @@ void cmVisualStudio10TargetGenerator::WriteMSToolConfigurationValues(
this->ASanEnabledConfigurations.end()) {
e1.Element("EnableAsan", "true");
}
+ if (this->FuzzerEnabledConfigurations.find(config) !=
+ this->FuzzerEnabledConfigurations.end()) {
+ e1.Element("EnableFuzzer", "true");
+ }
{
auto s = this->SpectreMitigation.find(config);
if (s != this->SpectreMitigation.end()) {
@@ -2875,7 +2895,7 @@ void cmVisualStudio10TargetGenerator::WritePathAndIncrementalLinkOptions(
Elem& e0)
{
cmStateEnums::TargetType ttype = this->GeneratorTarget->GetType();
- if (ttype > cmStateEnums::GLOBAL_TARGET) {
+ if (ttype > cmStateEnums::INTERFACE_LIBRARY) {
return;
}
if (this->ProjectType == VsProjectType::csproj) {
@@ -3117,6 +3137,7 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
this->LangForClCompile = langForClCompile;
if (!langForClCompile.empty()) {
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
+ cmBuildStep::Compile,
langForClCompile, configName);
this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget,
langForClCompile, configName);
@@ -3128,10 +3149,17 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
}
// Check if ASan is enabled.
- if (flags.find("/fsanitize=address") != std::string::npos) {
+ if (flags.find("/fsanitize=address") != std::string::npos ||
+ flags.find("-fsanitize=address") != std::string::npos) {
this->ASanEnabledConfigurations.insert(configName);
}
+ // Check if (lib)Fuzzer is enabled.
+ if (flags.find("/fsanitize=fuzzer") != std::string::npos ||
+ flags.find("-fsanitize=fuzzer") != std::string::npos) {
+ this->FuzzerEnabledConfigurations.insert(configName);
+ }
+
// Precompile Headers
std::string pchHeader =
this->GeneratorTarget->GetPchHeader(configName, linkLanguage);
@@ -3173,7 +3201,9 @@ bool cmVisualStudio10TargetGenerator::ComputeClOptions(
// anymore, because cmGeneratorTarget may not be aware that the
// target uses C++/CLI.
if (flags.find("/clr") != std::string::npos ||
- defineFlags.find("/clr") != std::string::npos) {
+ flags.find("-clr") != std::string::npos ||
+ defineFlags.find("/clr") != std::string::npos ||
+ defineFlags.find("-clr") != std::string::npos) {
if (configName == this->Configurations[0]) {
std::string message = "For the target \"" +
this->GeneratorTarget->GetName() +
@@ -3492,8 +3522,8 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaOptions(
// Get compile flags for CUDA in this directory.
std::string flags;
- this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, "CUDA",
- configName);
+ this->LocalGenerator->AddLanguageFlags(
+ flags, this->GeneratorTarget, cmBuildStep::Compile, "CUDA", configName);
this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, "CUDA",
configName);
@@ -3685,21 +3715,28 @@ bool cmVisualStudio10TargetGenerator::ComputeCudaLinkOptions(
this->GeneratorTarget->GetLinkOptions(linkOpts, configName, "CUDA");
// LINK_OPTIONS are escaped.
this->LocalGenerator->AppendCompileOptions(linkFlags, linkOpts);
+
+ cmComputeLinkInformation* pcli =
+ this->GeneratorTarget->GetLinkInformation(configName);
+ if (doDeviceLinking && pcli) {
+
+ cmLinkLineDeviceComputer computer(
+ this->LocalGenerator,
+ this->LocalGenerator->GetStateSnapshot().GetDirectory());
+ std::string ignored_;
+ this->LocalGenerator->GetDeviceLinkFlags(computer, configName, ignored_,
+ linkFlags, ignored_, ignored_,
+ this->GeneratorTarget);
+
+ this->LocalGenerator->AddLanguageFlagsForLinking(
+ linkFlags, this->GeneratorTarget, "CUDA", configName);
+ }
cudaLinkOptions.AppendFlagString("AdditionalOptions", linkFlags);
// For static libraries that have device linking enabled compute
// the libraries
if (this->GeneratorTarget->GetType() == cmStateEnums::STATIC_LIBRARY &&
doDeviceLinking) {
- cmComputeLinkInformation* pcli =
- this->GeneratorTarget->GetLinkInformation(configName);
- if (!pcli) {
- cmSystemTools::Error(
- "CMake can not compute cmComputeLinkInformation for target: " +
- this->Name);
- return false;
- }
-
cmComputeLinkInformation& cli = *pcli;
cmLinkLineDeviceComputer computer(
this->LocalGenerator,
@@ -3757,7 +3794,8 @@ bool cmVisualStudio10TargetGenerator::ComputeMasmOptions(
std::string flags;
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
- "ASM_MASM", configName);
+ cmBuildStep::Compile, "ASM_MASM",
+ configName);
masmOptions.Parse(flags);
@@ -3809,7 +3847,8 @@ bool cmVisualStudio10TargetGenerator::ComputeNasmOptions(
std::string flags;
this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget,
- "ASM_NASM", configName);
+ cmBuildStep::Compile, "ASM_NASM",
+ configName);
flags += " -f";
flags += this->Makefile->GetSafeDefinition("CMAKE_ASM_NASM_OBJECT_FORMAT");
nasmOptions.Parse(flags);
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 8d777a3..17dcecd 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -231,6 +231,7 @@ private:
bool TargetCompileAsWinRT;
std::set<std::string> IPOEnabledConfigurations;
std::set<std::string> ASanEnabledConfigurations;
+ std::set<std::string> FuzzerEnabledConfigurations;
std::map<std::string, std::string> SpectreMitigation;
cmGlobalVisualStudio10Generator* const GlobalGenerator;
cmLocalVisualStudio10Generator* const LocalGenerator;
diff --git a/Source/cmVisualStudioGeneratorOptions.cxx b/Source/cmVisualStudioGeneratorOptions.cxx
index 00c65ed..16584f5 100644
--- a/Source/cmVisualStudioGeneratorOptions.cxx
+++ b/Source/cmVisualStudioGeneratorOptions.cxx
@@ -161,71 +161,12 @@ bool cmVisualStudioGeneratorOptions::UsingSBCS() const
void cmVisualStudioGeneratorOptions::FixCudaCodeGeneration()
{
- // Extract temporary values stored by our flag table.
- FlagValue arch = this->TakeFlag("cmake-temp-arch");
- FlagValue code = this->TakeFlag("cmake-temp-code");
- FlagValue gencode = this->TakeFlag("cmake-temp-gencode");
-
- // No -code allowed without -arch.
- if (arch.empty()) {
- code.clear();
- }
-
- // Create a CodeGeneration field with [arch],[code] syntax in each entry.
- // CUDA will convert it to `-gencode=arch=[arch],code="[code],[arch]"`.
- FlagValue& result = this->FlagMap["CodeGeneration"];
-
- // If there are no flags, leave the CodeGeneration field empty.
- if (arch.empty() && gencode.empty()) {
- return;
- }
-
- // First entries for the -arch=<arch> [-code=<code>,...] pair.
- if (!arch.empty()) {
- std::string arch_name = arch[0];
- if (arch_name == "all" || arch_name == "all-major" ||
- arch_name == "native") {
- AppendFlagString("AdditionalOptions", "-arch=" + arch_name);
- return;
- }
- std::vector<std::string> codes;
- if (!code.empty()) {
- codes = cmTokenize(code[0], ",");
- }
- if (codes.empty()) {
- codes.push_back(arch_name);
- // nvcc -arch=<arch> has a special case that allows a real
- // architecture to be specified instead of a virtual arch.
- // It translates to -arch=<virtual> -code=<real>.
- cmSystemTools::ReplaceString(arch_name, "sm_", "compute_");
- }
- for (std::string const& c : codes) {
- std::string entry = arch_name + "," + c;
- result.push_back(entry);
- }
- }
-
- // Now add entries for the following signatures:
- // -gencode=<arch>,<code>
- // -gencode=<arch>,[<code1>,<code2>]
- // -gencode=<arch>,"<code1>,<code2>"
- for (std::string const& e : gencode) {
- std::string entry = e;
- cmSystemTools::ReplaceString(entry, "arch=", "");
- cmSystemTools::ReplaceString(entry, "code=", "");
- cmSystemTools::ReplaceString(entry, "[", "");
- cmSystemTools::ReplaceString(entry, "]", "");
- cmSystemTools::ReplaceString(entry, "\"", "");
-
- std::vector<std::string> codes = cmTokenize(entry, ",");
- if (codes.size() >= 2) {
- auto gencode_arch = cm::cbegin(codes);
- for (auto ci = gencode_arch + 1; ci != cm::cend(codes); ++ci) {
- std::string code_entry = *gencode_arch + "," + *ci;
- result.push_back(code_entry);
- }
- }
- }
+ // Create an empty CodeGeneration field, and pass the the actual
+ // compile flags via additional options so that we have consistent
+ // behavior and avoid issues with MSBuild extensions injecting
+ // virtual code when we request real only.
+ FlagValue& code_gen_flag = this->FlagMap["CodeGeneration"];
+ code_gen_flag = "";
}
void cmVisualStudioGeneratorOptions::FixManifestUACFlags()
diff --git a/Source/cmWhileCommand.cxx b/Source/cmWhileCommand.cxx
index fb94273..e80d1fc 100644
--- a/Source/cmWhileCommand.cxx
+++ b/Source/cmWhileCommand.cxx
@@ -96,7 +96,7 @@ bool cmWhileFunctionBlocker::Replay(std::vector<cmListFileFunction> functions,
cmExecutionStatus status(mf);
mf.ExecuteCommand(fn, status);
if (status.GetReturnInvoked()) {
- inStatus.SetReturnInvoked();
+ inStatus.SetReturnInvoked(status.GetReturnVariables());
return true;
}
if (status.GetBreakInvoked()) {
diff --git a/Source/cmXCodeScheme.cxx b/Source/cmXCodeScheme.cxx
index adc500a..e727d22 100644
--- a/Source/cmXCodeScheme.cxx
+++ b/Source/cmXCodeScheme.cxx
@@ -67,9 +67,14 @@ void cmXCodeScheme::WriteXCodeXCScheme(std::ostream& fout,
xout.Attribute("LastUpgradeVersion", WriteVersionString());
xout.Attribute("version", "1.3");
+ cmValue propDftCfg =
+ Target->GetTarget()->GetProperty("XCODE_SCHEME_LAUNCH_CONFIGURATION");
+ std::string launchConfiguration =
+ !propDftCfg.IsEmpty() ? *propDftCfg : "Debug";
+
WriteBuildAction(xout, container);
WriteTestAction(xout, FindConfiguration("Debug"), container);
- WriteLaunchAction(xout, FindConfiguration("Debug"), container);
+ WriteLaunchAction(xout, FindConfiguration(launchConfiguration), container);
WriteProfileAction(xout, FindConfiguration("Release"));
WriteAnalyzeAction(xout, FindConfiguration("Debug"));
WriteArchiveAction(xout, FindConfiguration("Release"));
@@ -147,7 +152,15 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
"Xcode.DebuggerFoundation.Debugger.LLDB");
xout.Attribute("selectedLauncherIdentifier",
"Xcode.DebuggerFoundation.Launcher.LLDB");
- xout.Attribute("launchStyle", "0");
+ {
+ cmValue launchMode =
+ this->Target->GetTarget()->GetProperty("XCODE_SCHEME_LAUNCH_MODE");
+ std::string value = "0"; // == 'AUTO'
+ if (launchMode && *launchMode == "WAIT") {
+ value = "1";
+ }
+ xout.Attribute("launchStyle", value);
+ }
WriteCustomWorkingDirectory(xout, configuration);
xout.Attribute("ignoresPersistentStateOnLaunch", "NO");
@@ -190,6 +203,23 @@ void cmXCodeScheme::WriteLaunchAction(cmXMLWriter& xout,
WriteLaunchActionAttribute(xout, "enableUBSanitizer",
"XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER");
+
+ if (cmValue value = this->Target->GetTarget()->GetProperty(
+ "XCODE_SCHEME_ENABLE_GPU_API_VALIDATION")) {
+ if (value.IsOff()) {
+ xout.Attribute("enableGPUValidationMode",
+ "1"); // unset means YES, "1" means NO
+ }
+ }
+
+ if (cmValue value = this->Target->GetTarget()->GetProperty(
+ "XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION")) {
+ if (value.IsOn()) {
+ xout.Attribute("enableGPUShaderValidationMode",
+ "2"); // unset means NO, "2" means YES
+ }
+ }
+
WriteLaunchActionAttribute(
xout, "stopOnEveryUBSanitizerIssue",
"XCODE_SCHEME_UNDEFINED_BEHAVIOUR_SANITIZER_STOP");
diff --git a/Source/cmake.cxx b/Source/cmake.cxx
index 1c1cab3..281e63f 100644
--- a/Source/cmake.cxx
+++ b/Source/cmake.cxx
@@ -3,6 +3,7 @@
#include "cmake.h"
#include <algorithm>
+#include <array>
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -62,6 +63,7 @@
#if !defined(CMAKE_BOOTSTRAP)
# include <unordered_map>
+# include <cm3p/curl/curl.h>
# include <cm3p/json/writer.h>
# include "cmFileAPI.h"
@@ -251,6 +253,8 @@ Json::Value cmake::ReportCapabilitiesJson() const
std::vector<cmake::GeneratorInfo> generatorInfoList;
this->GetRegisteredGenerators(generatorInfoList);
+ auto* curlVersion = curl_version_info(CURLVERSION_FIRST);
+
JsonValueMapType generatorMap;
for (cmake::GeneratorInfo const& gi : generatorInfoList) {
if (gi.isAlias) { // skip aliases, they are there for compatibility reasons
@@ -285,6 +289,7 @@ Json::Value cmake::ReportCapabilitiesJson() const
obj["generators"] = generators;
obj["fileApi"] = cmFileAPI::ReportCapabilities();
obj["serverMode"] = false;
+ obj["tls"] = static_cast<bool>(curlVersion->features & CURL_VERSION_SSL);
return obj;
}
@@ -777,6 +782,7 @@ enum class ListPresets
Configure,
Build,
Test,
+ Package,
All,
};
}
@@ -951,7 +957,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
CommandArgument::Values::One,
[](std::string const& value, cmake* state) -> bool {
const auto logLevel = StringToLogLevel(value);
- if (logLevel == LogLevel::LOG_UNDEFINED) {
+ if (logLevel == Message::LogLevel::LOG_UNDEFINED) {
cmSystemTools::Error(
"Invalid level specified for --log-level");
return false;
@@ -967,7 +973,7 @@ void cmake::SetArgs(const std::vector<std::string>& args)
CommandArgument::Values::One,
[](std::string const& value, cmake* state) -> bool {
const auto logLevel = StringToLogLevel(value);
- if (logLevel == LogLevel::LOG_UNDEFINED) {
+ if (logLevel == Message::LogLevel::LOG_UNDEFINED) {
cmSystemTools::Error(
"Invalid level specified for --loglevel");
return false;
@@ -1132,6 +1138,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
listPresets = ListPresets::Build;
} else if (value == "test") {
listPresets = ListPresets::Test;
+ } else if (value == "package") {
+ listPresets = ListPresets::Package;
} else if (value == "all") {
listPresets = ListPresets::All;
} else {
@@ -1282,9 +1290,13 @@ void cmake::SetArgs(const std::vector<std::string>& args)
cmCMakePresetsGraph presetsGraph;
auto result = presetsGraph.ReadProjectPresets(this->GetHomeDirectory());
if (result != cmCMakePresetsGraph::ReadFileResult::READ_OK) {
- cmSystemTools::Error(
+ std::string errorMsg =
cmStrCat("Could not read presets from ", this->GetHomeDirectory(),
- ": ", cmCMakePresetsGraph::ResultToString(result)));
+ ": ", cmCMakePresetsGraph::ResultToString(result));
+ if (!presetsGraph.errors.empty()) {
+ errorMsg = cmStrCat(errorMsg, "\nErrors:\n", presetsGraph.errors);
+ }
+ cmSystemTools::Error(errorMsg);
return;
}
@@ -1295,6 +1307,8 @@ void cmake::SetArgs(const std::vector<std::string>& args)
presetsGraph.PrintBuildPresetList();
} else if (listPresets == ListPresets::Test) {
presetsGraph.PrintTestPresetList();
+ } else if (listPresets == ListPresets::Package) {
+ presetsGraph.PrintPackagePresetList();
} else if (listPresets == ListPresets::All) {
presetsGraph.PrintAllPresets();
}
@@ -1398,23 +1412,52 @@ void cmake::SetArgs(const std::vector<std::string>& args)
#endif
}
-cmake::LogLevel cmake::StringToLogLevel(const std::string& levelStr)
-{
- using LevelsPair = std::pair<std::string, LogLevel>;
- static const std::vector<LevelsPair> levels = {
- { "error", LogLevel::LOG_ERROR }, { "warning", LogLevel::LOG_WARNING },
- { "notice", LogLevel::LOG_NOTICE }, { "status", LogLevel::LOG_STATUS },
- { "verbose", LogLevel::LOG_VERBOSE }, { "debug", LogLevel::LOG_DEBUG },
- { "trace", LogLevel::LOG_TRACE }
+namespace {
+using LevelsPair = std::pair<cm::string_view, Message::LogLevel>;
+using LevelsPairArray = std::array<LevelsPair, 7>;
+const LevelsPairArray& getStringToLogLevelPairs()
+{
+ static const LevelsPairArray levels = {
+ { { "error", Message::LogLevel::LOG_ERROR },
+ { "warning", Message::LogLevel::LOG_WARNING },
+ { "notice", Message::LogLevel::LOG_NOTICE },
+ { "status", Message::LogLevel::LOG_STATUS },
+ { "verbose", Message::LogLevel::LOG_VERBOSE },
+ { "debug", Message::LogLevel::LOG_DEBUG },
+ { "trace", Message::LogLevel::LOG_TRACE } }
};
+ return levels;
+}
+} // namespace
- const auto levelStrLowCase = cmSystemTools::LowerCase(levelStr);
+Message::LogLevel cmake::StringToLogLevel(cm::string_view levelStr)
+{
+ const LevelsPairArray& levels = getStringToLogLevelPairs();
+
+ const auto levelStrLowCase =
+ cmSystemTools::LowerCase(std::string{ levelStr });
+ // NOLINTNEXTLINE(readability-qualified-auto)
const auto it = std::find_if(levels.cbegin(), levels.cend(),
[&levelStrLowCase](const LevelsPair& p) {
return p.first == levelStrLowCase;
});
- return (it != levels.cend()) ? it->second : LogLevel::LOG_UNDEFINED;
+ return (it != levels.cend()) ? it->second : Message::LogLevel::LOG_UNDEFINED;
+}
+
+std::string cmake::LogLevelToString(Message::LogLevel level)
+{
+ const LevelsPairArray& levels = getStringToLogLevelPairs();
+
+ // NOLINTNEXTLINE(readability-qualified-auto)
+ const auto it =
+ std::find_if(levels.cbegin(), levels.cend(),
+ [&level](const LevelsPair& p) { return p.second == level; });
+ const cm::string_view levelStrLowerCase =
+ (it != levels.cend()) ? it->first : "undefined";
+ std::string levelStrUpperCase =
+ cmSystemTools::UpperCase(std::string{ levelStrLowerCase });
+ return levelStrUpperCase;
}
cmake::TraceFormat cmake::StringToTraceFormat(const std::string& traceStr)
@@ -2096,6 +2139,9 @@ int cmake::ActualConfigure()
this->UpdateConversionPathTable();
this->CleanupCommandsAndMacros();
+ cmSystemTools::RemoveADirectory(this->GetHomeOutputDirectory() +
+ "/CMakeFiles/CMakeScratch");
+
int res = this->DoPreConfigureChecks();
if (res < 0) {
return -2;
diff --git a/Source/cmake.h b/Source/cmake.h
index 3c6af17..8c0fece 100644
--- a/Source/cmake.h
+++ b/Source/cmake.h
@@ -119,19 +119,6 @@ public:
FIND_PACKAGE_MODE
};
- /** \brief Define log level constants. */
- enum LogLevel
- {
- LOG_UNDEFINED,
- LOG_ERROR,
- LOG_WARNING,
- LOG_NOTICE,
- LOG_STATUS,
- LOG_VERBOSE,
- LOG_DEBUG,
- LOG_TRACE
- };
-
/** \brief Define supported trace formats **/
enum TraceFormat
{
@@ -469,9 +456,10 @@ public:
bool WasLogLevelSetViaCLI() const { return this->LogLevelWasSetViaCLI; }
//! Get the selected log level for `message()` commands during the cmake run.
- LogLevel GetLogLevel() const { return this->MessageLogLevel; }
- void SetLogLevel(LogLevel level) { this->MessageLogLevel = level; }
- static LogLevel StringToLogLevel(const std::string& levelStr);
+ Message::LogLevel GetLogLevel() const { return this->MessageLogLevel; }
+ void SetLogLevel(Message::LogLevel level) { this->MessageLogLevel = level; }
+ static Message::LogLevel StringToLogLevel(cm::string_view levelStr);
+ static std::string LogLevelToString(Message::LogLevel level);
static TraceFormat StringToTraceFormat(const std::string& levelStr);
bool HasCheckInProgress() const
@@ -732,7 +720,7 @@ private:
std::set<std::string> DebugFindPkgs;
std::set<std::string> DebugFindVars;
- LogLevel MessageLogLevel = LogLevel::LOG_STATUS;
+ Message::LogLevel MessageLogLevel = Message::LogLevel::LOG_STATUS;
bool LogLevelWasSetViaCLI = false;
bool LogContext = false;
@@ -873,6 +861,7 @@ private:
F(cxx_std_17) \
F(cxx_std_20) \
F(cxx_std_23) \
+ F(cxx_std_26) \
FOR_EACH_CXX98_FEATURE(F) \
FOR_EACH_CXX11_FEATURE(F) \
FOR_EACH_CXX14_FEATURE(F)
@@ -883,7 +872,8 @@ private:
F(cuda_std_14) \
F(cuda_std_17) \
F(cuda_std_20) \
- F(cuda_std_23)
+ F(cuda_std_23) \
+ F(cuda_std_26)
#define FOR_EACH_HIP_FEATURE(F) \
F(hip_std_98) \
@@ -891,4 +881,5 @@ private:
F(hip_std_14) \
F(hip_std_17) \
F(hip_std_20) \
- F(hip_std_23)
+ F(hip_std_23) \
+ F(hip_std_26)
diff --git a/Source/cmakemain.cxx b/Source/cmakemain.cxx
index f931e9d..6f3d0eb 100644
--- a/Source/cmakemain.cxx
+++ b/Source/cmakemain.cxx
@@ -71,7 +71,7 @@ const char* cmDocumentationUsageNote[][2] = {
const char* cmDocumentationOptions[][2] = {
CMAKE_STANDARD_OPTIONS_TABLE,
{ "--preset <preset>,--preset=<preset>", "Specify a configure preset." },
- { "--list-presets", "List available presets." },
+ { "--list-presets[=<type>]", "List available presets." },
{ "-E", "CMake command mode." },
{ "-L[A][H]", "List non-advanced cached variables." },
{ "--fresh",
@@ -82,9 +82,9 @@ const char* cmDocumentationOptions[][2] = {
{ "-N", "View mode only." },
{ "-P <file>", "Process script mode." },
{ "--find-package", "Legacy pkg-config like mode. Do not use." },
- { "--graphviz=[file]",
- "Generate graphviz of dependencies, see "
- "CMakeGraphVizOptions.cmake for more." },
+ { "--graphviz=<file>",
+ "Generate graphviz of dependencies, see CMakeGraphVizOptions.cmake for "
+ "more." },
{ "--system-information [file]", "Dump information about this system." },
{ "--log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>",
"Set the verbosity of messages from CMake files. "
@@ -109,8 +109,7 @@ const char* cmDocumentationOptions[][2] = {
{ "--warn-uninitialized", "Warn about uninitialized values." },
{ "--no-warn-unused-cli", "Don't warn about command line options." },
{ "--check-system-vars",
- "Find problems with variable usage in system "
- "files." },
+ "Find problems with variable usage in system files." },
{ "--compile-no-warning-as-error",
"Ignore COMPILE_WARNING_AS_ERROR property and "
"CMAKE_COMPILE_WARNING_AS_ERROR variable." },
@@ -616,7 +615,7 @@ int do_build(int ac, char const* const* av)
" <dir> = Project binary directory to be built.\n"
" --preset <preset>, --preset=<preset>\n"
" = Specify a build preset.\n"
- " --list-presets\n"
+ " --list-presets[=<type>]\n"
" = List available build presets.\n"
" --parallel [<jobs>], -j [<jobs>]\n"
" = Build in parallel using the given number of jobs. \n"
@@ -627,14 +626,14 @@ int do_build(int ac, char const* const* av)
" specifies a default parallel level when this "
"option\n"
" is not given.\n"
- " --target <tgt>..., -t <tgt>... \n"
+ " -t <tgt>..., --target <tgt>...\n"
" = Build <tgt> instead of default targets.\n"
" --config <cfg> = For multi-configuration tools, choose <cfg>.\n"
" --clean-first = Build target 'clean' first, then build.\n"
" (To clean only, use --target 'clean'.)\n"
" --resolve-package-references={on|only|off}\n"
" = Restore/resolve package references during build.\n"
- " --verbose, -v = Enable verbose output - if supported - including\n"
+ " -v, --verbose = Enable verbose output - if supported - including\n"
" the build commands to be executed. \n"
" -- = Pass remaining options to the native tool.\n"
;
diff --git a/Source/cmcldeps.cxx b/Source/cmcldeps.cxx
index 8921aa0..69eb19e 100644
--- a/Source/cmcldeps.cxx
+++ b/Source/cmcldeps.cxx
@@ -273,6 +273,7 @@ int main()
std::string clrest = rest;
// rc: /fo x.dir\x.rc.res -> cl: /out:x.dir\x.rc.res.dep.obj
clrest = replace(clrest, "/fo ", "/out:");
+ clrest = replace(clrest, "-fo ", "-out:");
clrest = replace(clrest, objfile, objfile + ".dep.obj ");
cl = "\"" + cl + "\" /P /DRC_INVOKED /TC ";
diff --git a/Source/cmcmd.cxx b/Source/cmcmd.cxx
index 9ab39f1..00c9bda 100644
--- a/Source/cmcmd.cxx
+++ b/Source/cmcmd.cxx
@@ -791,6 +791,10 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
}
if (args[1] == "env") {
+#ifndef CMAKE_BOOTSTRAP
+ cmSystemTools::EnvDiff env;
+#endif
+
auto ai = args.cbegin() + 2;
auto ae = args.cend();
for (; ai != ae; ++ai) {
@@ -803,16 +807,40 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
}
if (cmHasLiteralPrefix(a, "--unset=")) {
// Unset environment variable.
+#ifdef CMAKE_BOOTSTRAP
cmSystemTools::UnPutEnv(a.substr(8));
+#else
+ env.UnPutEnv(a.substr(8));
+#endif
+ } else if (a == "--modify") {
+#ifdef CMAKE_BOOTSTRAP
+ std::cerr
+ << "cmake -E env: --modify not available during bootstrapping\n";
+ return 1;
+#else
+ if (++ai == ae) {
+ std::cerr << "cmake -E env: --modify missing a parameter\n";
+ return 1;
+ }
+ std::string const& op = *ai;
+ if (!env.ParseOperation(op)) {
+ std::cerr << "cmake -E env: invalid parameter to --modify: " << op
+ << '\n';
+ return 1;
+ }
+#endif
} else if (!a.empty() && a[0] == '-') {
// Environment variable and command names cannot start in '-',
// so this must be an unknown option.
- std::cerr << "cmake -E env: unknown option '" << a << '\''
- << std::endl;
+ std::cerr << "cmake -E env: unknown option '" << a << "'\n";
return 1;
} else if (a.find('=') != std::string::npos) {
// Set environment variable.
+#ifdef CMAKE_BOOTSTRAP
cmSystemTools::PutEnv(a);
+#else
+ env.PutEnv(a);
+#endif
} else {
// This is the beginning of the command.
break;
@@ -820,10 +848,14 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
}
if (ai == ae) {
- std::cerr << "cmake -E env: no command given" << std::endl;
+ std::cerr << "cmake -E env: no command given\n";
return 1;
}
+#ifndef CMAKE_BOOTSTRAP
+ env.ApplyToCurrentEnv();
+#endif
+
// Execute command from remaining arguments.
std::vector<std::string> cmd(ai, ae);
int retval;
@@ -2242,13 +2274,18 @@ bool cmVSLink::Parse(std::vector<std::string>::const_iterator argBeg,
// Parse the link command to extract information we need.
for (; arg != argEnd; ++arg) {
if (cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL:YES") == 0 ||
- cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0) {
+ cmSystemTools::Strucmp(arg->c_str(), "-INCREMENTAL:YES") == 0 ||
+ cmSystemTools::Strucmp(arg->c_str(), "/INCREMENTAL") == 0 ||
+ cmSystemTools::Strucmp(arg->c_str(), "-INCREMENTAL") == 0) {
this->Incremental = true;
- } else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0) {
+ } else if (cmSystemTools::Strucmp(arg->c_str(), "/MANIFEST:NO") == 0 ||
+ cmSystemTools::Strucmp(arg->c_str(), "-MANIFEST:NO") == 0) {
this->LinkGeneratesManifest = false;
- } else if (cmHasLiteralPrefix(*arg, "/Fe")) {
+ } else if (cmHasLiteralPrefix(*arg, "/Fe") ||
+ cmHasLiteralPrefix(*arg, "-Fe")) {
this->TargetFile = arg->substr(3);
- } else if (cmHasLiteralPrefix(*arg, "/out:")) {
+ } else if (cmHasLiteralPrefix(*arg, "/out:") ||
+ cmHasLiteralPrefix(*arg, "-out:")) {
this->TargetFile = arg->substr(5);
}
}
diff --git a/Source/kwsys/Directory.cxx b/Source/kwsys/Directory.cxx
index d520c14..f239576 100644
--- a/Source/kwsys/Directory.cxx
+++ b/Source/kwsys/Directory.cxx
@@ -43,12 +43,12 @@ public:
{
std::string Name;
#if defined(_WIN32) && !defined(__CYGWIN__)
- _wfinddata_t FindData;
+ WIN32_FIND_DATAW FindData;
#endif
FileData(std::string name
#if defined(_WIN32) && !defined(__CYGWIN__)
,
- _wfinddata_t data
+ WIN32_FIND_DATAW data
#endif
)
: Name(std::move(name))
@@ -115,8 +115,8 @@ std::string Directory::GetFilePath(std::size_t i) const
bool Directory::FileIsDirectory(std::size_t i) const
{
#if defined(_WIN32) && !defined(__CYGWIN__)
- _wfinddata_t const& data = this->Internal->Files[i].FindData;
- return (data.attrib & FILE_ATTRIBUTE_DIRECTORY) != 0;
+ auto const& data = this->Internal->Files[i].FindData;
+ return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
#else
std::string const& path = this->GetFilePath(i);
return kwsys::SystemTools::FileIsDirectory(path);
@@ -127,9 +127,9 @@ bool Directory::FileIsSymlink(std::size_t i) const
{
std::string const& path = this->GetFilePath(i);
#if defined(_WIN32) && !defined(__CYGWIN__)
- _wfinddata_t const& data = this->Internal->Files[i].FindData;
+ auto const& data = this->Internal->Files[i].FindData;
return kwsys::SystemTools::FileIsSymlinkWithAttr(
- Encoding::ToWindowsExtendedPath(path), data.attrib);
+ Encoding::ToWindowsExtendedPath(path), data.dwFileAttributes);
#else
return kwsys::SystemTools::FileIsSymlink(path);
#endif
@@ -157,7 +157,7 @@ namespace KWSYS_NAMESPACE {
Status Directory::Load(std::string const& name, std::string* errorMessage)
{
this->Clear();
- intptr_t srchHandle;
+ HANDLE srchHandle;
char* buf;
size_t bufLength;
size_t n = name.size();
@@ -176,14 +176,14 @@ Status Directory::Load(std::string const& name, std::string* errorMessage)
snprintf(buf, bufLength, "%s/*", name.c_str());
}
}
- struct _wfinddata_t data; // data of current file
+ WIN32_FIND_DATAW data; // data of current file
// Now put them into the file array
srchHandle =
- _wfindfirst((wchar_t*)Encoding::ToWindowsExtendedPath(buf).c_str(), &data);
+ FindFirstFileW(Encoding::ToWindowsExtendedPath(buf).c_str(), &data);
delete[] buf;
- if (srchHandle == -1) {
+ if (srchHandle == INVALID_HANDLE_VALUE) {
Status status = Status::POSIX_errno();
if (errorMessage) {
*errorMessage = status.GetString();
@@ -193,10 +193,11 @@ Status Directory::Load(std::string const& name, std::string* errorMessage)
// Loop through names
do {
- this->Internal->Files.emplace_back(Encoding::ToNarrow(data.name), data);
- } while (_wfindnext(srchHandle, &data) != -1);
+ this->Internal->Files.emplace_back(Encoding::ToNarrow(data.cFileName),
+ data);
+ } while (FindNextFileW(srchHandle, &data));
this->Internal->Path = name;
- if (_findclose(srchHandle) == -1) {
+ if (!FindClose(srchHandle)) {
Status status = Status::POSIX_errno();
if (errorMessage) {
*errorMessage = status.GetString();
@@ -209,7 +210,7 @@ Status Directory::Load(std::string const& name, std::string* errorMessage)
unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
std::string* errorMessage)
{
- intptr_t srchHandle;
+ HANDLE srchHandle;
char* buf;
size_t bufLength;
size_t n = name.size();
@@ -222,13 +223,13 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
buf = new char[n + 2 + 1];
snprintf(buf, bufLength, "%s/*", name.c_str());
}
- struct _wfinddata_t data; // data of current file
+ WIN32_FIND_DATAW data; // data of current file
// Now put them into the file array
- srchHandle = _wfindfirst((wchar_t*)Encoding::ToWide(buf).c_str(), &data);
+ srchHandle = FindFirstFileW(Encoding::ToWide(buf).c_str(), &data);
delete[] buf;
- if (srchHandle == -1) {
+ if (srchHandle == INVALID_HANDLE_VALUE) {
if (errorMessage) {
if (unsigned int errorId = GetLastError()) {
LPSTR message = nullptr;
@@ -250,8 +251,8 @@ unsigned long Directory::GetNumberOfFilesInDirectory(const std::string& name,
unsigned long count = 0;
do {
count++;
- } while (_wfindnext(srchHandle, &data) != -1);
- _findclose(srchHandle);
+ } while (FindNextFileW(srchHandle, &data));
+ FindClose(srchHandle);
return count;
}
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx
index 5889a4b..a20901c 100644
--- a/Source/kwsys/SystemTools.cxx
+++ b/Source/kwsys/SystemTools.cxx
@@ -536,9 +536,11 @@ public:
StringMap TranslationMap;
#endif
#ifdef _WIN32
- static std::string GetCasePathName(std::string const& pathIn);
+ static std::string GetCasePathName(std::string const& pathIn,
+ bool const cache);
static std::string GetActualCaseForPathCached(std::string const& path);
static const char* GetEnvBuffered(const char* key);
+ std::map<std::string, std::string, SystemToolsPathCaseCmp> FindFileMap;
std::map<std::string, std::string, SystemToolsPathCaseCmp> PathCaseMap;
std::map<std::string, std::string> EnvMap;
#endif
@@ -571,7 +573,8 @@ public:
static SystemToolsStatic* SystemToolsStatics;
#ifdef _WIN32
-std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn)
+std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn,
+ bool const cache)
{
std::string casePath;
@@ -623,14 +626,31 @@ std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn)
} else {
std::string test_str = casePath;
test_str += path_components[idx];
- WIN32_FIND_DATAW findData;
- HANDLE hFind =
- ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), &findData);
- if (INVALID_HANDLE_VALUE != hFind) {
- path_components[idx] = Encoding::ToNarrow(findData.cFileName);
- ::FindClose(hFind);
- } else {
- converting = false;
+
+ bool found_in_cache = false;
+ if (cache) {
+ auto const it = SystemToolsStatics->FindFileMap.find(test_str);
+ if (it != SystemToolsStatics->FindFileMap.end()) {
+ path_components[idx] = it->second;
+ found_in_cache = true;
+ }
+ }
+
+ if (!found_in_cache) {
+ WIN32_FIND_DATAW findData;
+ HANDLE hFind =
+ ::FindFirstFileW(Encoding::ToWide(test_str).c_str(), &findData);
+ if (INVALID_HANDLE_VALUE != hFind) {
+ auto case_file_name = Encoding::ToNarrow(findData.cFileName);
+ if (cache) {
+ SystemToolsStatics->FindFileMap.emplace(test_str,
+ case_file_name);
+ }
+ path_components[idx] = std::move(case_file_name);
+ ::FindClose(hFind);
+ } else {
+ converting = false;
+ }
}
}
}
@@ -642,19 +662,16 @@ std::string SystemToolsStatic::GetCasePathName(std::string const& pathIn)
std::string SystemToolsStatic::GetActualCaseForPathCached(std::string const& p)
{
- // Check to see if actual case has already been called
- // for this path, and the result is stored in the PathCaseMap
- auto& pcm = SystemToolsStatics->PathCaseMap;
- {
- auto itr = pcm.find(p);
- if (itr != pcm.end()) {
- return itr->second;
- }
- }
- std::string casePath = SystemToolsStatic::GetCasePathName(p);
- if (casePath.size() <= MAX_PATH) {
- pcm[p] = casePath;
+ std::string casePath;
+
+ auto it = SystemToolsStatics->PathCaseMap.find(p);
+ if (it != SystemToolsStatics->PathCaseMap.end()) {
+ casePath = it->second;
+ } else {
+ casePath = SystemToolsStatic::GetCasePathName(p, true);
+ SystemToolsStatics->PathCaseMap.emplace(p, casePath);
}
+
return casePath;
}
#endif
@@ -3067,17 +3084,14 @@ std::string SystemTools::GetRealPath(const std::string& path,
return ret;
}
-bool SystemTools::FileIsDirectory(const std::string& inName)
+// Remove any trailing slash from the name except in a root component.
+static const char* RemoveTrailingSlashes(
+ const std::string& inName, char (&local_buffer)[KWSYS_SYSTEMTOOLS_MAXPATH],
+ std::string& string_buffer)
{
- if (inName.empty()) {
- return false;
- }
size_t length = inName.size();
const char* name = inName.c_str();
- // Remove any trailing slash from the name except in a root component.
- char local_buffer[KWSYS_SYSTEMTOOLS_MAXPATH];
- std::string string_buffer;
size_t last = length - 1;
if (last > 0 && (name[last] == '/' || name[last] == '\\') &&
strcmp(name, "/") != 0 && name[last - 1] != ':') {
@@ -3091,6 +3105,19 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
}
}
+ return name;
+}
+
+bool SystemTools::FileIsDirectory(const std::string& inName)
+{
+ if (inName.empty()) {
+ return false;
+ }
+
+ char local_buffer[KWSYS_SYSTEMTOOLS_MAXPATH];
+ std::string string_buffer;
+ const auto name = RemoveTrailingSlashes(inName, local_buffer, string_buffer);
+
// Now check the file node type.
#if defined(_WIN32)
DWORD attr =
@@ -3107,9 +3134,21 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
}
}
-bool SystemTools::FileIsExecutable(const std::string& name)
+bool SystemTools::FileIsExecutable(const std::string& inName)
{
- return !FileIsDirectory(name) && TestFileAccess(name, TEST_FILE_EXECUTE);
+#ifdef _WIN32
+ char local_buffer[KWSYS_SYSTEMTOOLS_MAXPATH];
+ std::string string_buffer;
+ const auto name = RemoveTrailingSlashes(inName, local_buffer, string_buffer);
+ const auto attr =
+ GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str());
+
+ // On Windows any file that exists and is not a directory is considered
+ // readable and therefore also executable:
+ return attr != INVALID_FILE_ATTRIBUTES && !(attr & FILE_ATTRIBUTE_DIRECTORY);
+#else
+ return !FileIsDirectory(inName) && TestFileAccess(inName, TEST_FILE_EXECUTE);
+#endif
}
#if defined(_WIN32)
@@ -3655,7 +3694,7 @@ std::string SystemTools::RelativePath(const std::string& local,
std::string SystemTools::GetActualCaseForPath(const std::string& p)
{
#ifdef _WIN32
- return SystemToolsStatic::GetCasePathName(p);
+ return SystemToolsStatic::GetCasePathName(p, false);
#else
return p;
#endif
diff --git a/Templates/MSBuild/FlagTables/v10_Cuda.json b/Templates/MSBuild/FlagTables/v10_Cuda.json
index b3230ac..b0765f5 100644
--- a/Templates/MSBuild/FlagTables/v10_Cuda.json
+++ b/Templates/MSBuild/FlagTables/v10_Cuda.json
@@ -70,118 +70,6 @@
]
},
{
- "name": "cmake-temp-gencode",
- "switch": "gencode=",
- "comment": "",
- "value": "",
- "flags": [
- "UserValue",
- "SemicolonAppendable"
- ]
- },
- {
- "name": "cmake-temp-gencode",
- "switch": "gencode",
- "comment": "",
- "value": "",
- "flags": [
- "UserFollowing",
- "SemicolonAppendable"
- ]
- },
- {
- "name": "cmake-temp-gencode",
- "switch": "-generate-code=",
- "comment": "",
- "value": "",
- "flags": [
- "UserValue",
- "SemicolonAppendable"
- ]
- },
- {
- "name": "cmake-temp-gencode",
- "switch": "-generate-code",
- "comment": "",
- "value": "",
- "flags": [
- "UserFollowing",
- "SemicolonAppendable"
- ]
- },
- {
- "name": "cmake-temp-code",
- "switch": "code=",
- "comment": "",
- "value": "",
- "flags": [
- "UserValue"
- ]
- },
- {
- "name": "cmake-temp-code",
- "switch": "code",
- "comment": "",
- "value": "",
- "flags": [
- "UserFollowing"
- ]
- },
- {
- "name": "cmake-temp-code",
- "switch": "-gpu-code=",
- "comment": "",
- "value": "",
- "flags": [
- "UserValue"
- ]
- },
- {
- "name": "cmake-temp-code",
- "switch": "-gpu-code",
- "comment": "",
- "value": "",
- "flags": [
- "UserFollowing"
- ]
- },
- {
- "name": "cmake-temp-arch",
- "switch": "arch=",
- "comment": "",
- "value": "",
- "flags": [
- "UserValue"
- ]
- },
- {
- "name": "cmake-temp-arch",
- "switch": "arch",
- "comment": "",
- "value": "",
- "flags": [
- "UserFollowing"
- ]
- },
- {
- "name": "cmake-temp-arch",
- "switch": "-gpu-architecture=",
- "comment": "",
- "value": "",
- "flags": [
- "UserValue"
- ]
- },
- {
- "name": "cmake-temp-arch",
- "switch": "-gpu-architecture",
- "comment": "",
- "value": "",
- "flags": [
- "UserFollowing"
- ]
- },
- {
"name": "FastMath",
"switch": "use_fast_math",
"comment": "",
diff --git a/Tests/Assembler/CMakeLists.txt b/Tests/Assembler/CMakeLists.txt
index 1b7e57d..8f6b355 100644
--- a/Tests/Assembler/CMakeLists.txt
+++ b/Tests/Assembler/CMakeLists.txt
@@ -24,6 +24,12 @@ if("${CMAKE_GENERATOR}" MATCHES "Makefile|Xcode|Ninja" AND
elseif("${CMAKE_SYSTEM_NAME};${CMAKE_SYSTEM_PROCESSOR}" STREQUAL "Darwin;arm64")
list(APPEND C_FLAGS -arch arm64)
endif()
+ if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
+ # Just in case the user is passing -flto, we need to pass -fno-lto to
+ # clang when generating the assembly file, or else clang will generate
+ # LLVM IR instead of assembly.
+ list(APPEND C_FLAGS -fno-lto)
+ endif()
# Clang on OS X, and perhaps other compilers, do not support -g
# for both generating and assembling, so drop it from generating.
list(REMOVE_ITEM C_FLAGS -g)
diff --git a/Tests/CMakeLib/testArgumentParser.cxx b/Tests/CMakeLib/testArgumentParser.cxx
index 965690c..e044794 100644
--- a/Tests/CMakeLib/testArgumentParser.cxx
+++ b/Tests/CMakeLib/testArgumentParser.cxx
@@ -1,57 +1,182 @@
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file Copyright.txt or https://cmake.org/licensing for details. */
+#include <functional>
#include <initializer_list>
#include <iostream>
+#include <map>
#include <string>
+#include <utility>
#include <vector>
+#include <cm/optional>
#include <cm/string_view>
#include <cmext/string_view>
#include "cmArgumentParser.h"
+#include "cmArgumentParserTypes.h"
namespace {
-struct Result
+struct Result : public ArgumentParser::ParseResult
{
bool Option1 = false;
bool Option2 = false;
std::string String1;
- std::string String2;
+ cm::optional<std::string> String2;
+ cm::optional<std::string> String3;
+ ArgumentParser::Maybe<std::string> String4;
+ ArgumentParser::NonEmpty<std::string> String5;
+ ArgumentParser::NonEmpty<std::string> String6;
- std::vector<std::string> List1;
- std::vector<std::string> List2;
- std::vector<std::string> List3;
+ ArgumentParser::NonEmpty<std::vector<std::string>> List1;
+ ArgumentParser::NonEmpty<std::vector<std::string>> List2;
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> List3;
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> List4;
+ cm::optional<ArgumentParser::NonEmpty<std::vector<std::string>>> List5;
+ cm::optional<ArgumentParser::MaybeEmpty<std::vector<std::string>>> List6;
std::vector<std::vector<std::string>> Multi1;
std::vector<std::vector<std::string>> Multi2;
- std::vector<std::vector<std::string>> Multi3;
+ cm::optional<std::vector<std::vector<std::string>>> Multi3;
+ cm::optional<std::vector<std::vector<std::string>>> Multi4;
+
+ cm::optional<std::string> Pos0;
+ cm::optional<std::string> Pos1;
+ cm::optional<std::string> Pos2;
+
+ bool Func0_ = false;
+ ArgumentParser::Continue Func0(cm::string_view)
+ {
+ Func0_ = true;
+ return ArgumentParser::Continue::No;
+ }
+
+ std::string Func1_;
+ ArgumentParser::Continue Func1(cm::string_view arg)
+ {
+ Func1_ = std::string(arg);
+ return ArgumentParser::Continue::No;
+ }
+
+ std::map<std::string, std::vector<std::string>> Func2_;
+ ArgumentParser::Continue Func2(cm::string_view key, cm::string_view arg)
+ {
+ Func2_[std::string(key)].emplace_back(arg);
+ return key == "FUNC_2b" ? ArgumentParser::Continue::Yes
+ : ArgumentParser::Continue::No;
+ }
+
+ std::vector<std::string> Func3_;
+ ArgumentParser::Continue Func3(cm::string_view arg)
+ {
+ Func3_.emplace_back(arg);
+ return ArgumentParser::Continue::Yes;
+ }
+
+ std::map<std::string, std::vector<std::string>> Func4_;
+ ArgumentParser::Continue Func4(cm::string_view key, cm::string_view arg)
+ {
+ Func4_[std::string(key)].emplace_back(arg);
+ return key == "FUNC_4b" ? ArgumentParser::Continue::Yes
+ : ArgumentParser::Continue::No;
+ }
+
+ ArgumentParser::Maybe<std::string> UnboundMaybe{ 'u', 'n', 'b', 'o',
+ 'u', 'n', 'd' };
+ ArgumentParser::MaybeEmpty<std::vector<std::string>> UnboundMaybeEmpty{
+ 1, "unbound"
+ };
+ ArgumentParser::NonEmpty<std::vector<std::string>> UnboundNonEmpty{
+ 1, "unbound"
+ };
+ ArgumentParser::NonEmpty<std::string> UnboundNonEmptyStr{ 'u', 'n', 'b', 'o',
+ 'u', 'n', 'd' };
+
+ std::vector<cm::string_view> ParsedKeywords;
};
std::initializer_list<cm::string_view> const args = {
/* clang-format off */
+ "pos0", // position index 0
"OPTION_1", // option
+ "pos2", // position index 2, ignored because after keyword
+ // "OPTION_2", // option that is not present
"STRING_1", // string arg missing value
- "STRING_2", "foo", "bar", // string arg + unparsed value
+ "STRING_2", "foo", "bar", // string arg + unparsed value, presence captured
+ // "STRING_3", // string arg that is not present
+ "STRING_4", // string arg allowed to be missing value
+ "STRING_5", "foo", // string arg that is not empty
+ "STRING_6", "", // string arg that is empty
"LIST_1", // list arg missing values
"LIST_2", "foo", "bar", // list arg with 2 elems
"LIST_3", "bar", // list arg ...
"LIST_3", "foo", // ... with continuation
+ "LIST_4", // list arg missing values, presence captured
+ // "LIST_5", // list arg that is not present
+ "LIST_6", // list arg allowed to be empty
"MULTI_2", // multi list with 0 lists
"MULTI_3", "foo", "bar", // multi list with first list with two elems
"MULTI_3", "bar", "foo", // multi list with second list with two elems
+ // "MULTI_4", // multi list arg that is not present
+ "FUNC_0", // callback arg missing value
+ "FUNC_1", "foo", "ign1", // callback with one arg + unparsed value
+ "FUNC_2a", "foo", "ign2", // callback with keyword-dependent arg count
+ "FUNC_2b", "bar", "zot", // callback with keyword-dependent arg count
+ "FUNC_3", "foo", "bar", // callback with list arg ...
+ "FUNC_4a", "foo", "ign4", // callback with keyword-dependent arg count
+ "FUNC_4b", "bar", "zot", // callback with keyword-dependent arg count
/* clang-format on */
};
bool verifyResult(Result const& result,
- std::vector<std::string> const& unparsedArguments,
- std::vector<std::string> const& keywordsMissingValue)
+ std::vector<std::string> const& unparsedArguments)
{
static std::vector<std::string> const foobar = { "foo", "bar" };
static std::vector<std::string> const barfoo = { "bar", "foo" };
- static std::vector<std::string> const missing = { "STRING_1", "LIST_1" };
+ static std::vector<std::string> const unbound = { "unbound" };
+ static std::vector<cm::string_view> const parsedKeywords = {
+ /* clang-format off */
+ "OPTION_1",
+ "STRING_1",
+ "STRING_2",
+ "STRING_4",
+ "STRING_5",
+ "STRING_6",
+ "LIST_1",
+ "LIST_2",
+ "LIST_3",
+ "LIST_3",
+ "LIST_4",
+ "LIST_6",
+ "MULTI_2",
+ "MULTI_3",
+ "MULTI_3",
+ "FUNC_0",
+ "FUNC_1",
+ "FUNC_2a",
+ "FUNC_2b",
+ "FUNC_3",
+ "FUNC_4a",
+ "FUNC_4b",
+ /* clang-format on */
+ };
+ static std::map<std::string, std::vector<std::string>> const func2map = {
+ { "FUNC_2a", { "foo" } }, { "FUNC_2b", { "bar", "zot" } }
+ };
+ static std::map<std::string, std::vector<std::string>> const func4map = {
+ { "FUNC_4a", { "foo" } }, { "FUNC_4b", { "bar", "zot" } }
+ };
+ static std::map<cm::string_view, std::string> const keywordErrors = {
+ { "STRING_1"_s, " missing required value\n" },
+ { "STRING_6"_s, " empty string not allowed\n" },
+ { "LIST_1"_s, " missing required value\n" },
+ { "LIST_4"_s, " missing required value\n" },
+ { "FUNC_0"_s, " missing required value\n" }
+ };
+ static std::vector<std::string> const unparsed = { "pos2", "bar", "ign1",
+ "ign2", "ign4" };
#define ASSERT_TRUE(x) \
do { \
@@ -61,26 +186,63 @@ bool verifyResult(Result const& result,
} \
} while (false)
+ ASSERT_TRUE(!result);
+
ASSERT_TRUE(result.Option1);
ASSERT_TRUE(!result.Option2);
ASSERT_TRUE(result.String1.empty());
- ASSERT_TRUE(result.String2 == "foo");
+ ASSERT_TRUE(result.String2);
+ ASSERT_TRUE(*result.String2 == "foo");
+ ASSERT_TRUE(!result.String3);
+ ASSERT_TRUE(result.String4.empty());
+ ASSERT_TRUE(result.String5 == "foo");
+ ASSERT_TRUE(result.String6.empty());
ASSERT_TRUE(result.List1.empty());
ASSERT_TRUE(result.List2 == foobar);
- ASSERT_TRUE(result.List3 == barfoo);
+ ASSERT_TRUE(result.List3);
+ ASSERT_TRUE(*result.List3 == barfoo);
+ ASSERT_TRUE(result.List4);
+ ASSERT_TRUE(result.List4->empty());
+ ASSERT_TRUE(!result.List5);
+ ASSERT_TRUE(result.List6);
+ ASSERT_TRUE(result.List6->empty());
ASSERT_TRUE(result.Multi1.empty());
ASSERT_TRUE(result.Multi2.size() == 1);
ASSERT_TRUE(result.Multi2[0].empty());
- ASSERT_TRUE(result.Multi3.size() == 2);
- ASSERT_TRUE(result.Multi3[0] == foobar);
- ASSERT_TRUE(result.Multi3[1] == barfoo);
+ ASSERT_TRUE(result.Multi3);
+ ASSERT_TRUE((*result.Multi3).size() == 2);
+ ASSERT_TRUE((*result.Multi3)[0] == foobar);
+ ASSERT_TRUE((*result.Multi3)[1] == barfoo);
+ ASSERT_TRUE(!result.Multi4);
+
+ ASSERT_TRUE(result.Pos0 == "pos0");
+ ASSERT_TRUE(!result.Pos1);
+ ASSERT_TRUE(!result.Pos2);
+
+ ASSERT_TRUE(result.Func0_ == false);
+ ASSERT_TRUE(result.Func1_ == "foo");
+ ASSERT_TRUE(result.Func2_ == func2map);
+ ASSERT_TRUE(result.Func3_ == foobar);
+ ASSERT_TRUE(result.Func4_ == func4map);
+
+ ASSERT_TRUE(unparsedArguments == unparsed);
- ASSERT_TRUE(unparsedArguments.size() == 1);
- ASSERT_TRUE(unparsedArguments[0] == "bar");
- ASSERT_TRUE(keywordsMissingValue == missing);
+ ASSERT_TRUE(result.UnboundMaybe == "unbound");
+ ASSERT_TRUE(result.UnboundMaybeEmpty == unbound);
+ ASSERT_TRUE(result.UnboundNonEmpty == unbound);
+ ASSERT_TRUE(result.UnboundNonEmptyStr == "unbound");
+
+ ASSERT_TRUE(result.ParsedKeywords == parsedKeywords);
+
+ ASSERT_TRUE(result.GetKeywordErrors().size() == keywordErrors.size());
+ for (auto const& ke : result.GetKeywordErrors()) {
+ auto const ki = keywordErrors.find(ke.first);
+ ASSERT_TRUE(ki != keywordErrors.end());
+ ASSERT_TRUE(ke.second == ki->second);
+ }
return true;
}
@@ -89,45 +251,116 @@ bool testArgumentParserDynamic()
{
Result result;
std::vector<std::string> unparsedArguments;
- std::vector<std::string> keywordsMissingValue;
-
- cmArgumentParser<void>{}
- .Bind("OPTION_1"_s, result.Option1)
- .Bind("OPTION_2"_s, result.Option2)
- .Bind("STRING_1"_s, result.String1)
- .Bind("STRING_2"_s, result.String2)
- .Bind("LIST_1"_s, result.List1)
- .Bind("LIST_2"_s, result.List2)
- .Bind("LIST_3"_s, result.List3)
- .Bind("MULTI_1"_s, result.Multi1)
- .Bind("MULTI_2"_s, result.Multi2)
- .Bind("MULTI_3"_s, result.Multi3)
- .Parse(args, &unparsedArguments, &keywordsMissingValue);
-
- return verifyResult(result, unparsedArguments, keywordsMissingValue);
+
+ std::function<ArgumentParser::Continue(cm::string_view, cm::string_view)>
+ func4 = [&result](cm::string_view key,
+ cm::string_view arg) -> ArgumentParser::Continue {
+ return result.Func4(key, arg);
+ };
+
+ static_cast<ArgumentParser::ParseResult&>(result) =
+ cmArgumentParser<void>{}
+ .Bind(0, result.Pos0)
+ .Bind(1, result.Pos1)
+ .Bind(2, result.Pos2)
+ .Bind("OPTION_1"_s, result.Option1)
+ .Bind("OPTION_2"_s, result.Option2)
+ .Bind("STRING_1"_s, result.String1)
+ .Bind("STRING_2"_s, result.String2)
+ .Bind("STRING_3"_s, result.String3)
+ .Bind("STRING_4"_s, result.String4)
+ .Bind("STRING_5"_s, result.String5)
+ .Bind("STRING_6"_s, result.String6)
+ .Bind("LIST_1"_s, result.List1)
+ .Bind("LIST_2"_s, result.List2)
+ .Bind("LIST_3"_s, result.List3)
+ .Bind("LIST_4"_s, result.List4)
+ .Bind("LIST_5"_s, result.List5)
+ .Bind("LIST_6"_s, result.List6)
+ .Bind("MULTI_1"_s, result.Multi1)
+ .Bind("MULTI_2"_s, result.Multi2)
+ .Bind("MULTI_3"_s, result.Multi3)
+ .Bind("MULTI_4"_s, result.Multi4)
+ .Bind("FUNC_0"_s,
+ [&result](cm::string_view arg) -> ArgumentParser::Continue {
+ return result.Func0(arg);
+ })
+ .Bind("FUNC_1"_s,
+ [&result](cm::string_view arg) -> ArgumentParser::Continue {
+ return result.Func1(arg);
+ })
+ .Bind("FUNC_2a"_s,
+ [&result](cm::string_view key, cm::string_view arg)
+ -> ArgumentParser::Continue { return result.Func2(key, arg); })
+ .Bind("FUNC_2b"_s,
+ [&result](cm::string_view key, cm::string_view arg)
+ -> ArgumentParser::Continue { return result.Func2(key, arg); })
+ .Bind("FUNC_3"_s,
+ [&result](cm::string_view arg) -> ArgumentParser::Continue {
+ return result.Func3(arg);
+ })
+ .Bind("FUNC_4a"_s, func4)
+ .Bind("FUNC_4b"_s, func4)
+ .BindParsedKeywords(result.ParsedKeywords)
+ .Parse(args, &unparsedArguments);
+
+ return verifyResult(result, unparsedArguments);
}
+static auto const parserStaticFunc4 =
+ [](Result& result, cm::string_view key,
+ cm::string_view arg) -> ArgumentParser::Continue {
+ return result.Func4(key, arg);
+};
+static auto const parserStatic = //
+ cmArgumentParser<Result>{}
+ .Bind(0, &Result::Pos0)
+ .Bind(1, &Result::Pos1)
+ .Bind(2, &Result::Pos2)
+ .Bind("OPTION_1"_s, &Result::Option1)
+ .Bind("OPTION_2"_s, &Result::Option2)
+ .Bind("STRING_1"_s, &Result::String1)
+ .Bind("STRING_2"_s, &Result::String2)
+ .Bind("STRING_3"_s, &Result::String3)
+ .Bind("STRING_4"_s, &Result::String4)
+ .Bind("STRING_5"_s, &Result::String5)
+ .Bind("STRING_6"_s, &Result::String6)
+ .Bind("LIST_1"_s, &Result::List1)
+ .Bind("LIST_2"_s, &Result::List2)
+ .Bind("LIST_3"_s, &Result::List3)
+ .Bind("LIST_4"_s, &Result::List4)
+ .Bind("LIST_5"_s, &Result::List5)
+ .Bind("LIST_6"_s, &Result::List6)
+ .Bind("MULTI_1"_s, &Result::Multi1)
+ .Bind("MULTI_2"_s, &Result::Multi2)
+ .Bind("MULTI_3"_s, &Result::Multi3)
+ .Bind("MULTI_4"_s, &Result::Multi4)
+ .Bind("FUNC_0"_s, &Result::Func0)
+ .Bind("FUNC_1"_s, &Result::Func1)
+ .Bind("FUNC_2a"_s, &Result::Func2)
+ .Bind("FUNC_2b"_s, &Result::Func2)
+ .Bind("FUNC_3"_s,
+ [](Result& result, cm::string_view arg) -> ArgumentParser::Continue {
+ return result.Func3(arg);
+ })
+ .Bind("FUNC_4a"_s, parserStaticFunc4)
+ .Bind("FUNC_4b"_s, parserStaticFunc4)
+ .BindParsedKeywords(&Result::ParsedKeywords)
+ /* keep semicolon on own line */;
+
bool testArgumentParserStatic()
{
- static auto const parser = //
- cmArgumentParser<Result>{}
- .Bind("OPTION_1"_s, &Result::Option1)
- .Bind("OPTION_2"_s, &Result::Option2)
- .Bind("STRING_1"_s, &Result::String1)
- .Bind("STRING_2"_s, &Result::String2)
- .Bind("LIST_1"_s, &Result::List1)
- .Bind("LIST_2"_s, &Result::List2)
- .Bind("LIST_3"_s, &Result::List3)
- .Bind("MULTI_1"_s, &Result::Multi1)
- .Bind("MULTI_2"_s, &Result::Multi2)
- .Bind("MULTI_3"_s, &Result::Multi3);
-
std::vector<std::string> unparsedArguments;
- std::vector<std::string> keywordsMissingValue;
- Result const result =
- parser.Parse(args, &unparsedArguments, &keywordsMissingValue);
+ Result const result = parserStatic.Parse(args, &unparsedArguments);
+ return verifyResult(result, unparsedArguments);
+}
- return verifyResult(result, unparsedArguments, keywordsMissingValue);
+bool testArgumentParserStaticBool()
+{
+ std::vector<std::string> unparsedArguments;
+ Result result;
+ ASSERT_TRUE(parserStatic.Parse(result, args, &unparsedArguments) == false);
+ return verifyResult(result, unparsedArguments);
}
} // namespace
@@ -144,5 +377,10 @@ int testArgumentParser(int /*unused*/, char* /*unused*/ [])
return -1;
}
+ if (!testArgumentParserStaticBool()) {
+ std::cout << "While executing testArgumentParserStaticBool().\n";
+ return -1;
+ }
+
return 0;
}
diff --git a/Tests/CMakeLib/testCMExtEnumSet.cxx b/Tests/CMakeLib/testCMExtEnumSet.cxx
index 64c437b..dbb0a54 100644
--- a/Tests/CMakeLib/testCMExtEnumSet.cxx
+++ b/Tests/CMakeLib/testCMExtEnumSet.cxx
@@ -191,6 +191,15 @@ void testEdition()
++failed;
}
}
+ {
+ cm::enum_set<Test> testSet1;
+ cm::enum_set<Test> testSet2{ Test::A, Test::C, Test::B };
+
+ testSet1 = { Test::A, Test::C, Test::B };
+ if (testSet1.size() != 3 || testSet1 != testSet2) {
+ ++failed;
+ }
+ }
}
}
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 24e98f4..b6fec4d 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -431,7 +431,7 @@ if(BUILD_TESTING)
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|[9][0-9])")
ADD_TEST_MACRO(CSharpOnly CSharpOnly)
- if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
+ if(NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
ADD_TEST_MACRO(CSharpLinkToCxx CSharpLinkToCxx)
ADD_TEST_MACRO(CSharpLinkFromCxx CSharpLinkFromCxx)
endif()
@@ -618,6 +618,11 @@ if(BUILD_TESTING)
set(Module.CheckIPOSupported-CXX_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_CXX=${CMake_TEST_IPO_WORKS_CXX})
ADD_TEST_MACRO(Module.CheckIPOSupported-CXX CheckIPOSupported-CXX)
+ if(CMake_TEST_CUDA)
+ ADD_TEST_MACRO(Module.CheckIPOSupported-CUDA CheckIPOSupported-CUDA)
+ set_property(TEST Module.CheckIPOSupported-CUDA APPEND PROPERTY LABELS "CUDA")
+ endif()
+
if(CMAKE_Fortran_COMPILER)
set(Module.CheckIPOSupported-Fortran_BUILD_OPTIONS -DCMake_TEST_IPO_WORKS_Fortran=${CMake_TEST_IPO_WORKS_Fortran})
ADD_TEST_MACRO(Module.CheckIPOSupported-Fortran CheckIPOSupported-Fortran)
@@ -1056,8 +1061,11 @@ if(BUILD_TESTING)
endif()
endif()
if(NSIS_MAKENSIS_EXECUTABLE)
- set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS}
- -DCPACK_BINARY_NSIS:BOOL=ON)
+ execute_process(COMMAND ${NSIS_MAKENSIS_EXECUTABLE} "-VERSION" ERROR_QUIET OUTPUT_QUIET RESULT_VARIABLE NSIS_OK)
+ if("${NSIS_OK}" STREQUAL "0")
+ set(CPackComponents_BUILD_OPTIONS ${CPackComponents_BUILD_OPTIONS}
+ -DCPACK_BINARY_NSIS:BOOL=ON)
+ endif()
endif()
add_test(CPackComponents ${CMAKE_CTEST_COMMAND}
@@ -1153,7 +1161,6 @@ if(BUILD_TESTING)
"components-source"
"components-shlibdeps1"
"components-depend1"
- "components-depend2"
"compression")
# Run additional tests if dpkg-shlibdeps is available (and is new enough version)
find_program(SHLIBDEPS_EXECUTABLE NAMES dpkg-shlibdeps)
@@ -1173,6 +1180,11 @@ if(BUILD_TESTING)
list(APPEND DEB_CONFIGURATIONS_TO_TEST "shlibdeps-with-private-lib-failure"
"shlibdeps-with-private-lib-success")
endif()
+ # Check if distro has symbols or shlibs data
+ file(GLOB SHLIBS_FILES_EXIST "/var/lib/dpkg/info/*.shlibs" "/var/lib/dpkg/info/*.symbols")
+ if(SHLIBS_FILES_EXIST)
+ list(APPEND DEB_CONFIGURATIONS_TO_TEST "components-depend2")
+ endif()
endif()
set(CPackGen "DEB")
@@ -1460,9 +1472,11 @@ if(BUILD_TESTING)
LTTngUST
ODBC
OpenACC
+ OpenAL
OpenCL
OpenGL
OpenMP
+ OpenSP
OpenSSL
MPI
PNG
@@ -1734,7 +1748,7 @@ if(BUILD_TESTING)
if(NOT CMake_TEST_EXTERNAL_CMAKE)
foreach(STP RANGE 2 12)
- if (STP EQUAL 6)
+ if (STP EQUAL 8)
set(pass_regex ".*using log and exp")
else()
set(pass_regex "The square root of 25 is 5")
@@ -2115,7 +2129,7 @@ if(BUILD_TESTING)
if(MSVC AND NOT MSVC_VERSION LESS 1310
AND (NOT CMAKE_GENERATOR MATCHES "Visual Studio 9 "
OR CMAKE_SIZEOF_VOID_P EQUAL 4)
- AND (NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
+ AND (NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
)
ADD_TEST_MACRO(VSMASM VSMASM)
endif()
@@ -2127,7 +2141,7 @@ if(BUILD_TESTING)
if(NOT "${CMAKE_GENERATOR}" MATCHES "Visual Studio 9 "
AND NOT CMAKE_GENERATOR_TOOLSET STREQUAL "v90"
- AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
+ AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
ADD_TEST_MACRO(VSWindowsFormsResx VSWindowsFormsResx)
ADD_TEST_MACRO(VSManagedCustomCommand)
endif()
@@ -2665,7 +2679,10 @@ if(BUILD_TESTING)
endif()
if(NOT DEFINED CMake_TEST_CTestUpdate_HG AND HG_EXECUTABLE
AND (UNIX OR NOT "${HG_EXECUTABLE}" MATCHES "cygwin"))
- set(CMake_TEST_CTestUpdate_HG 1)
+ execute_process(COMMAND "${HG_EXECUTABLE}" --version OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE HG_RV)
+ if(HG_RV EQUAL 0)
+ set(CMake_TEST_CTestUpdate_HG 1)
+ endif()
endif()
if(CMake_TEST_CTestUpdate_HG)
if(NOT HG_EXECUTABLE)
@@ -3367,56 +3384,70 @@ if(BUILD_TESTING)
set(JavaExportImport_BUILD_OPTIONS -DCMake_TEST_NESTED_MAKE_PROGRAM:FILEPATH=${CMake_TEST_EXPLICIT_MAKE_PROGRAM})
ADD_TEST_MACRO(JavaExportImport JavaExportImport)
- get_filename_component(JNIPATH ${Java_JAVAC_EXECUTABLE} PATH)
+ get_filename_component(JAVACPATH ${Java_JAVAC_EXECUTABLE} REALPATH)
+ get_filename_component(JNIPATH ${JAVACPATH} PATH)
find_file(JNI_H jni.h
"${JNIPATH}/../include"
"${JNIPATH}/../java/include")
if(JNI_H AND EXISTS "${JNI_H}") # in case jni.h is a broken symlink
file(READ "${JNI_H}" JNI_FILE)
if("${JNI_FILE}" MATCHES "JDK1_2")
- add_test(NAME Java.Jar COMMAND ${CMAKE_CTEST_COMMAND}
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/Java"
- "${CMake_BINARY_DIR}/Tests/JavaJar"
- ${build_generator_args}
- --build-project hello
- --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJar/"
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>)
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJar")
- # For next tests, java tool must have same architecture as toolchain
- math(EXPR _object_mode "${CMAKE_SIZEOF_VOID_P} * 8")
execute_process(
COMMAND "${Java_JAVA_EXECUTABLE}" -version
OUTPUT_VARIABLE _version ERROR_VARIABLE _version RESULT_VARIABLE _result
)
- if(_result EQUAL 0 AND _version MATCHES "${_object_mode}-Bit")
- ## next test is valid only if Java version is less than 1.10
- if ("${Java_VERSION}" VERSION_LESS 1.10)
- add_test(NAME Java.Javah COMMAND ${CMAKE_CTEST_COMMAND}
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/JavaJavah"
- "${CMake_BINARY_DIR}/Tests/JavaJavah"
- ${build_generator_args}
- --build-project helloJavah
- --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJavah/"
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>)
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJavah")
+
+ # E2K has broken Java RVM before 3.5.2
+ if (CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "e2k" AND _result EQUAL 0)
+ string(REGEX MATCH "RVM ([0-9.]+)" RVMVER "${_version}")
+ # Consider empty match a broken version too
+ if("${CMAKE_MATCH_1}" VERSION_LESS "3.5.2")
+ set(BROKEN_RVM TRUE)
endif()
- ## next test is valid only if Java is, at least, version 1.8
- if (NOT "${Java_VERSION}" VERSION_LESS 1.8)
- add_test(NAME Java.NativeHeaders COMMAND ${CMAKE_CTEST_COMMAND}
- --build-and-test
- "${CMake_SOURCE_DIR}/Tests/JavaNativeHeaders"
- "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders"
- ${build_generator_args}
- --build-project helloJavaNativeHeaders
- --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/"
- --build-target install
- --build-options
- "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/Install"
- --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>)
- list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders")
+ endif()
+
+ if(NOT BROKEN_RVM)
+ add_test(NAME Java.Jar COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIG>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/Java"
+ "${CMake_BINARY_DIR}/Tests/JavaJar"
+ ${build_generator_args}
+ --build-project hello
+ --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJar/"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>)
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJar")
+
+ # For next tests, java tool must have same architecture as toolchain
+ math(EXPR _object_mode "${CMAKE_SIZEOF_VOID_P} * 8")
+ if(_result EQUAL 0 AND _version MATCHES "${_object_mode}-Bit")
+ ## next test is valid only if Java version is less than 1.10
+ if ("${Java_VERSION}" VERSION_LESS 1.10)
+ add_test(NAME Java.Javah COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIG>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/JavaJavah"
+ "${CMake_BINARY_DIR}/Tests/JavaJavah"
+ ${build_generator_args}
+ --build-project helloJavah
+ --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaJavah/"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>)
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaJavah")
+ endif()
+ ## next test is valid only if Java is, at least, version 1.8
+ if (NOT "${Java_VERSION}" VERSION_LESS 1.8)
+ add_test(NAME Java.NativeHeaders COMMAND ${CMAKE_CTEST_COMMAND} -C $<CONFIG>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/JavaNativeHeaders"
+ "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders"
+ ${build_generator_args}
+ --build-project helloJavaNativeHeaders
+ --build-run-dir "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/"
+ --build-target install
+ --build-options
+ "-DCMAKE_INSTALL_PREFIX:PATH=${CMake_BINARY_DIR}/Tests/JavaNativeHeaders/Install"
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIG>)
+ list(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/JavaNativeHeaders")
+ endif()
endif()
endif()
endif()
diff --git a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
index 49a4041..0907d03 100644
--- a/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
+++ b/Tests/CMakeOnly/AllFindModules/CMakeLists.txt
@@ -56,6 +56,15 @@ macro(check_version_string MODULE_NAME VERSION_VAR)
if (NOT _exclude_pos EQUAL -1)
message(STATUS "excluding check of ${VERSION_VAR}='${${VERSION_VAR}}' due to local configuration")
elseif (${MODULE_NAME}_FOUND)
+
+ unset(SKIP_CHECK)
+ if(${MODULE_NAME} STREQUAL "HG")
+ execute_process(COMMAND "${HG_EXECUTABLE}" --version OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE HG_RV)
+ if(NOT HG_RV EQUAL 0)
+ message(WARNING "Broken HG executable detected, skipping")
+ set(SKIP_CHECK TRUE)
+ endif()
+ endif()
if (DEFINED ${VERSION_VAR})
message(STATUS "${VERSION_VAR}='${${VERSION_VAR}}'")
if (NOT ${VERSION_VAR} MATCHES "^[0-9]")
@@ -71,7 +80,9 @@ macro(check_version_string MODULE_NAME VERSION_VAR)
message(SEND_ERROR "unexpected: ${VERSION_VAR} is NOT VERSION_GREATER 0")
endif()
else()
- message(SEND_ERROR "${MODULE_NAME}_FOUND is set but version number variable ${VERSION_VAR} is NOT DEFINED")
+ if(NOT SKIP_CHECK)
+ message(SEND_ERROR "${MODULE_NAME}_FOUND is set but version number variable ${VERSION_VAR} is NOT DEFINED")
+ endif()
endif()
endif ()
endmacro()
diff --git a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
index 63c234a..7acfcd9 100644
--- a/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
+++ b/Tests/CMakeTests/ImplicitLinkInfoTest.cmake.in
@@ -13,72 +13,84 @@ set(linux64_gcc_text " /usr/lib/gcc/x86_64-linux-gnu/4.3.3/collect2 --eh-frame-h
set(linux64_gcc_libs "gcc;gcc_s;c;gcc;gcc_s")
set(linux64_gcc_dirs "/usr/lib/gcc/x86_64-linux-gnu/4.3.3;/usr/lib;/lib;/usr/lib/x86_64-linux-gnu")
list(APPEND platforms linux64_gcc)
+list(APPEND langs C)
# g++ dummy.cxx -v
set(linux64_g++_text " /usr/lib/gcc/x86_64-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../.. -L/usr/lib/x86_64-linux-gnu /tmp/ccalRBlq.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crtn.o")
set(linux64_g++_libs "stdc++;m;gcc_s;gcc;c;gcc_s;gcc")
set(linux64_g++_dirs "/usr/lib/gcc/x86_64-linux-gnu/4.3.3;/usr/lib;/lib;/usr/lib/x86_64-linux-gnu")
list(APPEND platforms linux64_g++)
+list(APPEND langs CXX)
# f95 dummy.f -v
set(linux64_f95_text " /usr/lib/gcc/x86_64-linux-gnu/4.3.3/collect2 --eh-frame-hdr -m elf_x86_64 --hash-style=both -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3 -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib -L/lib/../lib -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../.. -L/usr/lib/x86_64-linux-gnu /tmp/ccAVcN7N.o -lgfortranbegin -lgfortran -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.3.3/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.3.3/../../../../lib/crtn.o")
set(linux64_f95_libs "gfortranbegin;gfortran;m;gcc_s;gcc;c;gcc_s;gcc")
set(linux64_f95_dirs "/usr/lib/gcc/x86_64-linux-gnu/4.3.3;/usr/lib;/lib;/usr/lib/x86_64-linux-gnu")
list(APPEND platforms linux64_f95)
+list(APPEND langs Fortran)
# suncc dummy.c '-#'
set(linux64_suncc_text "/usr/bin/ld --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/sun/sunstudio12/prod/lib/amd64/crti.o /opt/sun/sunstudio12/prod/lib/amd64/crt1x.o /opt/sun/sunstudio12/prod/lib/amd64/values-xa.o dummy.o -Y \"/opt/sun/sunstudio12/prod/lib/amd64:/lib64:/usr/lib64\" -Qy -lc /opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a /opt/sun/sunstudio12/prod/lib/amd64/crtn.o")
set(linux64_suncc_libs "c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
set(linux64_suncc_dirs "/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
list(APPEND platforms linux64_suncc)
+list(APPEND langs C)
# sunCC dummy.cxx -v
set(linux64_sunCC_text "/opt/sun/sunstudio12/prod/lib/amd64/ld -u __1cH__CimplKcplus_init6F_v_ --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -R/opt/sun/sunstudio12/lib/rw7/amd64:/opt/sun/sunstudio12/lib/amd64:/opt/sun/sunstudio12/rtlibs/amd64:/opt/sun/lib/rtlibs/amd64:/opt/SUNWspro/lib/amd64:/lib64:/usr/lib64 -o a.out /opt/sun/sunstudio12/prod/lib/amd64/crti.o /opt/sun/sunstudio12/prod/lib/amd64/CCrti.o /opt/sun/sunstudio12/prod/lib/amd64/crt1x.o -Y P,/opt/sun/sunstudio12/lib/rw7/amd64:/opt/sun/sunstudio12/lib/amd64:/opt/sun/sunstudio12/rtlibs/amd64:/opt/sun/sunstudio12/prod/lib/rw7/amd64:/opt/sun/sunstudio12/prod/lib/amd64:/lib64:/usr/lib64 dummy.o -lCstd -lCrun -lm -lc /opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a /opt/sun/sunstudio12/prod/lib/amd64/CCrtn.o /opt/sun/sunstudio12/prod/lib/amd64/crtn.o >&/tmp/ld.04973.2.err")
set(linux64_sunCC_libs "Cstd;Crun;m;c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
set(linux64_sunCC_dirs "/opt/sun/sunstudio12/lib/rw7/amd64;/opt/sun/sunstudio12/lib/amd64;/opt/sun/sunstudio12/rtlibs/amd64;/opt/sun/sunstudio12/prod/lib/rw7/amd64;/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
list(APPEND platforms linux64_sunCC)
+list(APPEND langs CXX)
# sunf90 dummy.f -v
set(linux64_sunf90_text "/usr/bin/ld --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -R/opt/sun/sunstudio12/lib/amd64:/opt/sun/sunstudio12/rtlibs/amd64:/opt/sun/lib/rtlibs/amd64 -o a.out /opt/sun/sunstudio12/prod/lib/amd64/crti.o /opt/sun/sunstudio12/prod/lib/amd64/crt1x.o /opt/sun/sunstudio12/prod/lib/amd64/values-xi.o -Y P,/opt/sun/sunstudio12/lib/amd64:/opt/sun/sunstudio12/rtlibs/amd64:/opt/sun/sunstudio12/prod/lib/amd64:/lib64:/usr/lib64 dummy.o -lfui -lfai -lfsu -Bdynamic -lmtsk -lpthread -lm -lc /opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a /opt/sun/sunstudio12/prod/lib/amd64/crtn.o")
set(linux64_sunf90_libs "fui;fai;fsu;mtsk;pthread;m;c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
set(linux64_sunf90_dirs "/opt/sun/sunstudio12/lib/amd64;/opt/sun/sunstudio12/rtlibs/amd64;/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
list(APPEND platforms linux64_sunf90)
+list(APPEND langs Fortran)
# icc dummy.c -v
set(linux64_icc_text "ld /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crt1.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crti.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o --eh-frame-hdr -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /tmp/iccBP8OfN.o -L/opt/compiler/intel/compiler/11.0/lib/intel64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.. -L/lib64 -L/lib -L/usr/lib64 -L/usr/lib -Bstatic -limf -lsvml -Bdynamic -lm -Bstatic -lipgo -ldecimal -lirc -Bdynamic -lgcc_s -lgcc -Bstatic -lirc -Bdynamic -lc -lgcc_s -lgcc -Bstatic -lirc_s -Bdynamic -ldl -lc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o")
set(linux64_icc_libs "imf;svml;m;ipgo;decimal;irc;gcc_s;gcc;irc;c;gcc_s;gcc;irc_s;dl;c")
set(linux64_icc_dirs "/opt/compiler/intel/compiler/11.0/lib/intel64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2;/usr/lib64;/lib64;/usr/x86_64-suse-linux/lib;/lib;/usr/lib")
list(APPEND platforms linux64_icc)
+list(APPEND langs C)
# icxx dummy.cxx -v
set(linux64_icxx_text "ld /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crt1.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crti.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o --eh-frame-hdr -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /tmp/icpc270GoT.o -L/opt/compiler/intel/compiler/11.0/lib/intel64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.. -L/lib64 -L/lib -L/usr/lib64 -L/usr/lib -Bstatic -limf -lsvml -Bdynamic -lm -Bstatic -lipgo -ldecimal -Bdynamic -lstdc++ -Bstatic -lirc -Bdynamic -lgcc_s -lgcc -Bstatic -lirc -Bdynamic -lc -lgcc_s -lgcc -Bstatic -lirc_s -Bdynamic -ldl -lc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o")
set(linux64_icxx_libs "imf;svml;m;ipgo;decimal;stdc++;irc;gcc_s;gcc;irc;c;gcc_s;gcc;irc_s;dl;c")
set(linux64_icxx_dirs "/opt/compiler/intel/compiler/11.0/lib/intel64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2;/usr/lib64;/lib64;/usr/x86_64-suse-linux/lib;/lib;/usr/lib")
list(APPEND platforms linux64_icxx)
+list(APPEND langs CXX)
# ifort dummy.f -v
set(linux64_ifort_text "ld --eh-frame-hdr -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out -L/opt/compiler/intel/compiler/11.0/lib/intel64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../x86_64-suse-linux/lib -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../.. -L/lib64 -L/lib -L/usr/lib64 -L/usr/lib /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crt1.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crti.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o /opt/compiler/intel/compiler/11.0/lib/intel64/for_main.o dum.cxx -Bstatic -lifport -lifcore -limf -lsvml -Bdynamic -lm -Bstatic -lipgo -lirc -Bdynamic -lpthread -lc -lgcc_s -lgcc -Bstatic -lirc_s -Bdynamic -ldl -lc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/../../../../lib64/crtn.o")
set(linux64_ifort_libs "ifport;ifcore;imf;svml;m;ipgo;irc;pthread;c;gcc_s;gcc;irc_s;dl;c")
set(linux64_ifort_dirs "/opt/compiler/intel/compiler/11.0/lib/intel64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2;/usr/lib64;/lib64;/usr/x86_64-suse-linux/lib;/lib;/usr/lib")
list(APPEND platforms linux64_ifort)
+list(APPEND langs Fortran)
# pgcc dummy.c -v
set(linux64_pgcc_text "/usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /opt/compiler/pgi/linux86-64/8.0-3/lib/trace_init.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/compiler/pgi/linux86-64/8.0-3/lib/pgi.ld -L/opt/compiler/pgi/linux86-64/8.0-3/lib -L/usr/lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 /tmp/pgcc7OscXa5ur7Zk.o -rpath /opt/compiler/pgi/linux86-64/8.0-3/lib -lnspgc -lpgc -lm -lgcc -lc -lgcc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/crtn.o")
set(linux64_pgcc_libs "nspgc;pgc;m;gcc;c;gcc")
set(linux64_pgcc_dirs "/opt/compiler/pgi/linux86-64/8.0-3/lib;/usr/lib64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2")
list(APPEND platforms linux64_pgcc)
+list(APPEND langs C)
# pgCC dummy.cxx -v
set(linux64_pgCC_text "/usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /opt/compiler/pgi/linux86-64/8.0-3/lib/trace_init.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/compiler/pgi/linux86-64/8.0-3/lib/pgi.ld -L/opt/compiler/pgi/linux86-64/8.0-3/lib -L/usr/lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 /tmp/pgCCFhjcDt1fs1Ki.o -rpath /opt/compiler/pgi/linux86-64/8.0-3/lib -lstd -lC -lnspgc -lpgc -lm -lgcc -lc -lgcc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/crtn.o")
set(linux64_pgCC_libs "std;C;nspgc;pgc;m;gcc;c;gcc")
set(linux64_pgCC_dirs "/opt/compiler/pgi/linux86-64/8.0-3/lib;/usr/lib64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2")
list(APPEND platforms linux64_pgCC)
+list(APPEND langs CXX)
# pgf90 dummy.f -v
set(linux64_pgf90_text "/usr/bin/ld /usr/lib64/crt1.o /usr/lib64/crti.o /opt/compiler/pgi/linux86-64/8.0-3/lib/trace_init.o /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtbegin.o /opt/compiler/pgi/linux86-64/8.0-3/lib/f90main.o -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/compiler/pgi/linux86-64/8.0-3/lib/pgi.ld -L/opt/compiler/pgi/linux86-64/8.0-3/lib -L/usr/lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.1.2 /tmp/pgf90QOIc_eB9xY5h.o -rpath /opt/compiler/pgi/linux86-64/8.0-3/lib -lpgf90 -lpgf90_rpm1 -lpgf902 -lpgf90rtl -lpgftnrtl -lnspgc -lpgc -lrt -lpthread -lm -lgcc -lc -lgcc /usr/lib64/gcc/x86_64-suse-linux/4.1.2/crtend.o /usr/lib64/crtn.o")
set(linux64_pgf90_libs "pgf90;pgf90_rpm1;pgf902;pgf90rtl;pgftnrtl;nspgc;pgc;rt;pthread;m;gcc;c;gcc")
set(linux64_pgf90_dirs "/opt/compiler/pgi/linux86-64/8.0-3/lib;/usr/lib64;/usr/lib64/gcc/x86_64-suse-linux/4.1.2")
list(APPEND platforms linux64_pgf90)
+list(APPEND langs Fortran)
# nagfor dummy.f -Wl,-v
set(linux64_nagfor_text " /usr/libexec/gcc/x86_64-redhat-linux/4.4.5/collect2 --no-add-needed --eh-frame-hdr --build-id -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/4.4.5/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/4.4.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.5 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../.. /usr/local/NAG/lib/f90_init.o /usr/local/NAG/lib/quickfit.o dummy.o -rpath /usr/local/NAG/lib /usr/local/NAG/lib/libf53.so /usr/local/NAG/lib/libf53.a -lm -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/4.4.5/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.4.5/../../../../lib64/crtn.o")
@@ -86,6 +98,7 @@ set(linux64_nagfor_libs "/usr/local/NAG/lib/f90_init.o;/usr/local/NAG/lib/quickf
set(linux64_nagfor_dirs "/usr/lib/gcc/x86_64-redhat-linux/4.4.5;/usr/lib64;/lib64;/usr/lib")
set(linux64_nagfor_obj_regex "^/usr/local/NAG/lib")
list(APPEND platforms linux64_nagfor)
+list(APPEND langs Fortran)
# absoft dummy.f -X -v
set(linux64_absoft_text "collect2 version 4.4.5 (x86-64 Linux/ELF)
@@ -93,6 +106,7 @@ set(linux64_absoft_text "collect2 version 4.4.5 (x86-64 Linux/ELF)
set(linux64_absoft_libs "af90math;afio;amisc;absoftmain;af77math;m;mv;pthread;gcc;gcc_s;c;gcc;gcc_s")
set(linux64_absoft_dirs "/opt/absoft11.1/lib64;/usr/lib/gcc/x86_64-linux-gnu/4.4.5;/usr/lib;/lib")
list(APPEND platforms linux64_absoft)
+list(APPEND langs Fortran)
# gcc dummy.c -v # in strange path
set(linux64_test1_text "
@@ -101,12 +115,14 @@ ${linux64_gcc_text}")
set(linux64_test1_libs "${linux64_gcc_libs}")
set(linux64_test1_dirs "${linux64_gcc_dirs}")
list(APPEND platforms linux64_test1)
+list(APPEND langs C)
# sunCC dummy.cxx -v # extra slashes
set(linux64_test2_text "/usr/bin/ld --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 /opt/sun/sunstudio12/prod/lib/amd64//crti.o /opt/sun/sunstudio12/prod/lib/amd64/crt1x.o /opt/sun/sunstudio12/prod/lib/amd64/values-xa.o dummy.o -Y \"/opt/sun/sunstudio12/prod/lib//amd64:/lib64:/usr//lib64\" -Qy -lc /opt/sun/sunstudio12/prod/lib/amd64//libc_supp.a /opt/sun/sunstudio12/prod/lib/amd64/crtn.o")
set(linux64_test2_libs "c;/opt/sun/sunstudio12/prod/lib/amd64/libc_supp.a")
set(linux64_test2_dirs "/opt/sun/sunstudio12/prod/lib/amd64;/lib64;/usr/lib64")
list(APPEND platforms linux64_test2)
+list(APPEND langs CXX)
# -specs=redhat-hardened-ld
set(linux64_test3_text "COLLECT_GCC_OPTIONS='-specs=/usr/lib/rpm/redhat/redhat-hardened-ld' '-v' '-O2' '-g' '-pipe' '-Wall' '-Werror=format-security' '-fexceptions' '-fstack-protector-strong' '--param' 'ssp-buffer-size=4' '-grecord-gcc-switches' '-specs=/usr/lib/rpm/redhat/redhat-hardened-cc1' '-m64' '-mtune=generic' '-I' '/usr/lib64/gfortran/modules' '-o' 'a.out' '-rdynamic' '-shared-libgcc' '-march=x86-64' '-pie'
@@ -114,12 +130,14 @@ set(linux64_test3_text "COLLECT_GCC_OPTIONS='-specs=/usr/lib/rpm/redhat/redhat-h
set(linux64_test3_libs "gfortran;m;gcc_s;gcc;quadmath;m;gcc_s;gcc;c;gcc_s;gcc")
set(linux64_test3_dirs "/usr/lib/gcc/x86_64-redhat-linux/5.1.1;/usr/lib64;/lib64;/usr/lib")
list(APPEND platforms linux64_test3)
+list(APPEND langs Fortran)
# clang -fsanitize=memory
set(linux64_clang_sanitize_memory_text [[ "/usr/bin/ld" --hash-style=both --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../.. -L/usr/lib/llvm-3.8/bin/../lib -L/lib -L/usr/lib -whole-archive /usr/lib/llvm-3.8/bin/../lib/clang/3.8.0/lib/linux/libclang_rt.msan-x86_64.a -no-whole-archive --dynamic-list=/usr/lib/llvm-3.8/bin/../lib/clang/3.8.0/lib/linux/libclang_rt.msan-x86_64.a.syms /tmp/dummy-27898d.o --no-as-needed -lpthread -lrt -lm -ldl -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../x86_64-linux-gnu/crtn.o]])
set(linux64_clang_sanitize_memory_libs "pthread;rt;m;dl;gcc;gcc_s;c;gcc;gcc_s")
set(linux64_clang_sanitize_memory_dirs "/usr/lib/gcc/x86_64-linux-gnu/5.4.0;/usr/lib/x86_64-linux-gnu;/lib/x86_64-linux-gnu;/lib64;/usr/lib;/usr/lib/llvm-3.8/lib;/lib")
list(APPEND platforms linux64_clang_sanitize_memory)
+list(APPEND langs C)
#-----------------------------------------------------------------------------
# Mac
@@ -144,12 +162,14 @@ set(mac_i686_gcc_Wlv_libs "gcc")
set(mac_i686_gcc_Wlv_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib")
set(mac_i686_gcc_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
list(APPEND platforms mac_i686_gcc_Wlv)
+list(APPEND langs C)
# gcc -arch i686 dummy.c -v
set(mac_i686_gcc_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccnhXAGL.o -lSystem -lgcc -lSystem")
set(mac_i686_gcc_libs "gcc")
set(mac_i686_gcc_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
list(APPEND platforms mac_i686_gcc)
+list(APPEND langs C)
# g++ -arch i686 dummy.cxx -v -Wl,-v
set(mac_i686_g++_Wlv_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccEXXICh.o -lstdc++ -lSystem -lgcc -lSystem
@@ -171,12 +191,14 @@ set(mac_i686_g++_Wlv_libs "stdc++;gcc")
set(mac_i686_g++_Wlv_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib")
set(mac_i686_g++_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
list(APPEND platforms mac_i686_g++_Wlv)
+list(APPEND langs CXX)
# g++ -arch i686 dummy.cxx -v
set(mac_i686_g++_text " /usr/libexec/gcc/i686-apple-darwin10/4.2.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.6.o -L/usr/lib/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../../i686-apple-darwin10/4.2.1 -L/usr/lib/gcc/i686-apple-darwin10/4.2.1/../../.. /var/tmp//ccEXXICh.o -lstdc++ -lSystem -lgcc -lSystem")
set(mac_i686_g++_libs "stdc++;gcc")
set(mac_i686_g++_dirs "/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
list(APPEND platforms mac_i686_g++)
+list(APPEND langs CXX)
# gfortran dummy.f -v -Wl,-v
set(mac_i686_gfortran_Wlv_text " /usr/local/libexec/gcc/i386-apple-darwin9.7.0/4.4.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//cc9zXNax.o -v -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem
@@ -195,12 +217,14 @@ set(mac_i686_gfortran_Wlv_libs "gfortranbegin;gfortran;gcc_s.10.5;gcc")
set(mac_i686_gfortran_Wlv_dirs "/usr/local/lib/gcc/i386-apple-darwin9.7.0/4.4.1;/usr/local/lib;/usr/lib")
set(mac_i686_gfortran_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
list(APPEND platforms mac_i686_gfortran_Wlv)
+list(APPEND langs Fortran)
# gfortran dummy.f -v
set(mac_i686_gfortran_text " /usr/libexec/gcc/i386-apple-darwin9.7.0/4.4.1/collect2 -dynamic -arch i386 -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1 -L/usr/lib/gcc -L/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1/../../.. /var/tmp//ccgqbX5P.o -lgfortranbegin -lgfortran -lgcc_s.10.5 -lgcc -lSystem")
set(mac_i686_gfortran_libs "gfortranbegin;gfortran;gcc_s.10.5;gcc")
set(mac_i686_gfortran_dirs "/usr/lib/gcc/i386-apple-darwin9.7.0/4.4.1;/usr/lib/gcc;/usr/lib")
list(APPEND platforms mac_i686_gfortran)
+list(APPEND langs Fortran)
# gcc -arch ppc dummy.c -v -Wl,-v
set(mac_ppc_gcc_Wlv_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//cclziQY4.o -v -lgcc -lSystemStubs -lSystem
@@ -222,12 +246,14 @@ set(mac_ppc_gcc_Wlv_libs "gcc")
set(mac_ppc_gcc_Wlv_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib")
set(mac_ppc_gcc_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
list(APPEND platforms mac_ppc_gcc_Wlv)
+list(APPEND langs C)
# gcc -arch ppc dummy.c -v
set(mac_ppc_gcc_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccdcolsP.o -lgcc -lSystemStubs -lSystem")
set(mac_ppc_gcc_libs "gcc")
set(mac_ppc_gcc_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib")
list(APPEND platforms mac_ppc_gcc)
+list(APPEND langs C)
# g++ -arch ppc dummy.cxx -v -Wl,-v
set(mac_ppc_g++_Wlv_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccaFTkwq.o -v -lstdc++ -lgcc -lSystemStubs -lSystem
@@ -249,12 +275,14 @@ set(mac_ppc_g++_Wlv_libs "stdc++;gcc")
set(mac_ppc_g++_Wlv_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib;/usr/local/lib")
set(mac_ppc_g++_Wlv_fwks "/Library/Frameworks;/System/Library/Frameworks")
list(APPEND platforms mac_ppc_g++_Wlv)
+list(APPEND langs CXX)
# g++ -arch ppc dummy.cxx -v
set(mac_ppc_g++_text " /usr/libexec/gcc/powerpc-apple-darwin10/4.2.1/collect2 -dynamic -arch ppc -macosx_version_min 10.6.0 -weak_reference_mismatches non-weak -o a.out -lcrt1.10.5.o -L/usr/lib/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../../powerpc-apple-darwin10/4.2.1 -L/usr/lib/gcc/powerpc-apple-darwin10/4.2.1/../../.. /var/tmp//ccbjB6Lj.o -lstdc++ -lgcc -lSystemStubs -lSystem")
set(mac_ppc_g++_libs "stdc++;gcc")
set(mac_ppc_g++_dirs "/usr/lib/powerpc-apple-darwin10/4.2.1;/usr/lib/gcc/powerpc-apple-darwin10/4.2.1;/usr/lib")
list(APPEND platforms mac_ppc_g++)
+list(APPEND langs CXX)
# absoft dummy.f -X -v
set(mac_absoft_text "collect2 version 4.2.1 (Apple Inc. build 5664) (i686 Darwin)
@@ -263,12 +291,14 @@ set(mac_absoft_text "collect2 version 4.2.1 (Apple Inc. build 5664) (i686 Darwin
set(mac_absoft_libs "af90math;afio;amisc;absoftmain;af77math;m;mv;gcc")
set(mac_absoft_dirs "/Applications/Absoft11.1/lib;/usr/lib/i686-apple-darwin10/4.2.1;/usr/lib/gcc/i686-apple-darwin10/4.2.1;/usr/lib")
list(APPEND platforms mac_absoft)
+list(APPEND langs Fortran)
# Xcode 8.3: clang++ dummy.cpp -v
set(mac_clang_v_text " \"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld\" -demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -macosx_version_min 10.12.0 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk -o a.out /var/folders/hc/95l7dhnx459c57g4yg_6yd8c0000gp/T/dummy-384ea1.o -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/8.1.0/lib/darwin/libclang_rt.osx.a")
set(mac_clang_v_libs "c++")
set(mac_clang_v_dirs "")
list(APPEND platforms mac_clang_v)
+list(APPEND langs CXX)
#-----------------------------------------------------------------------------
# Sun
@@ -278,24 +308,28 @@ set(sun_cc_text "/usr/ccs/bin/ld /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/pro
set(sun_cc_libs "c")
set(sun_cc_dirs "/opt/SUNWspro/prod/lib/v8plus;/opt/SUNWspro/prod/lib;/usr/ccs/lib;/lib;/usr/lib")
list(APPEND platforms sun_cc)
+list(APPEND langs C)
# CC dummy.cxx -v
set(sun_CC_text "/usr/ccs/bin/ld -u __1cH__CimplKcplus_init6F_v_ -zld32=-S/opt/SUNWspro/prod/lib/libldstab_ws.so -zld64=-S/opt/SUNWspro/prod/lib/v9/libldstab_ws.so -zld32=-S/opt/SUNWspro/prod/lib/libCCexcept.so.1 -zld64=-S/opt/SUNWspro/prod/lib/v9/libCCexcept.so.1 -R/opt/SUNWspro/lib/rw7:/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/lib:/usr/ccs/lib:/lib:/usr/lib -o a.out /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/CCrti.o /opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/misalign.o /opt/SUNWspro/prod/lib/values-xa.o -Y P,/opt/SUNWspro/lib/rw7:/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/prod/lib/rw7:/opt/SUNWspro/prod/lib/v8plus:/opt/SUNWspro/lib:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib dummy.o -lCstd -lCrun -lm -lc /opt/SUNWspro/prod/lib/CCrtn.o /opt/SUNWspro/prod/lib/crtn.o >&/tmp/ld.14846.2.err")
set(sun_CC_libs "Cstd;Crun;m;c")
set(sun_CC_dirs "/opt/SUNWspro/lib/rw7;/opt/SUNWspro/lib/v8plus;/opt/SUNWspro/prod/lib/rw7;/opt/SUNWspro/prod/lib/v8plus;/opt/SUNWspro/lib;/opt/SUNWspro/prod/lib;/usr/ccs/lib;/lib;/usr/lib")
list(APPEND platforms sun_CC)
+list(APPEND langs CXX)
# f77 dummy.f -v
set(sun_f77_text "/usr/ccs/bin/ld -t -R/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/lib -o a.out /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/misalign.o /opt/SUNWspro/prod/lib/values-xi.o -Y P,/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/prod/lib/v8plus:/opt/SUNWspro/lib:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib dummy.o -lf77compat -zallextract -lompstubs -zdefaultextract -lfui -lfai -lfai2 -lfsumai -lfprodai -lfminlai -lfmaxlai -lfminvai -lfmaxvai -lfsu -lsunmath -lm -lc /opt/SUNWspro/prod/lib/crtn.o")
set(sun_f77_libs "f77compat;-zallextract;ompstubs;-zdefaultextract;fui;fai;fai2;fsumai;fprodai;fminlai;fmaxlai;fminvai;fmaxvai;fsu;sunmath;m;c")
set(sun_f77_dirs "/opt/SUNWspro/lib/v8plus;/opt/SUNWspro/prod/lib/v8plus;/opt/SUNWspro/lib;/opt/SUNWspro/prod/lib;/usr/ccs/lib;/lib;/usr/lib")
list(APPEND platforms sun_f77)
+list(APPEND langs Fortran)
# f90 dummy.f -v
set(sun_f90_text "/usr/ccs/bin/ld -t -R/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/lib -o a.out /opt/SUNWspro/prod/lib/crti.o /opt/SUNWspro/prod/lib/crt1.o /opt/SUNWspro/prod/lib/misalign.o /opt/SUNWspro/prod/lib/values-xi.o -Y P,/opt/SUNWspro/lib/v8plus:/opt/SUNWspro/prod/lib/v8plus:/opt/SUNWspro/lib:/opt/SUNWspro/prod/lib:/usr/ccs/lib:/lib:/usr/lib dummy.o -zallextract -lompstubs -zdefaultextract -lfui -lfai -lfai2 -lfsumai -lfprodai -lfminlai -lfmaxlai -lfminvai -lfmaxvai -lfsu -lsunmath -lm -lc /opt/SUNWspro/prod/lib/crtn.o")
set(sun_f90_libs "-zallextract;ompstubs;-zdefaultextract;fui;fai;fai2;fsumai;fprodai;fminlai;fmaxlai;fminvai;fmaxvai;fsu;sunmath;m;c")
set(sun_f90_dirs "/opt/SUNWspro/lib/v8plus;/opt/SUNWspro/prod/lib/v8plus;/opt/SUNWspro/lib;/opt/SUNWspro/prod/lib;/usr/ccs/lib;/lib;/usr/lib")
list(APPEND platforms sun_f90)
+list(APPEND langs Fortran)
#-----------------------------------------------------------------------------
# AIX
@@ -305,12 +339,14 @@ set(aix_xlc_32_text "/bin/ld -b32 /lib/crt0.o -bpT:0x10000000 -bpD:0x20000000 du
set(aix_xlc_32_libs "xlopt;xl;c")
set(aix_xlc_32_dirs "/usr/vac/lib")
list(APPEND platforms aix_xlc_32)
+list(APPEND langs C)
# xlc -q64 dummy.c -V
set(aix_xlc_64_text "/bin/ld -b64 /lib/crt0_64.o -bpT:0x100000000 -bpD:0x110000000 dummy.o -L/usr/vac/lib -lxlopt -lxl -lc")
set(aix_xlc_64_libs "xlopt;xl;c")
set(aix_xlc_64_dirs "/usr/vac/lib")
list(APPEND platforms aix_xlc_64)
+list(APPEND langs C)
# xlC -q32 dummy.cxx -V
set(aix_xlC_32_text "
@@ -319,6 +355,7 @@ set(aix_xlC_32_text "
set(aix_xlC_32_libs "xlopt;xl;C;m;c")
set(aix_xlC_32_dirs "/usr/vac/lib;/usr/vacpp/lib")
list(APPEND platforms aix_xlC_32)
+list(APPEND langs CXX)
# xlC -q64 dummy.cxx -V
set(aix_xlC_64_text "
@@ -327,36 +364,42 @@ set(aix_xlC_64_text "
set(aix_xlC_64_libs "xlopt;xl;C;m;c")
set(aix_xlC_64_dirs "/usr/vac/lib;/usr/vacpp/lib")
list(APPEND platforms aix_xlC_64)
+list(APPEND langs CXX)
# xlf -q32 dummy.f -V
set(aix_xlf_32_text "/bin/ld -b32 /lib/crt0.o -bpT:0x10000000 -bpD:0x20000000 -bh:4 -bh:4 -bh:4 -bh:4 dummy.o -lxlf90 -L/usr/lpp/xlf/lib -lxlopt -lxlf -lxlomp_ser -lm -lc")
set(aix_xlf_32_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
set(aix_xlf_32_dirs "/usr/lpp/xlf/lib")
list(APPEND platforms aix_xlf_32)
+list(APPEND langs Fortran)
# xlf -q64 dummy.f -V
set(aix_xlf_64_text "/bin/ld -b64 /lib/crt0_64.o -bpT:0x100000000 -bpD:0x110000000 -bh:4 -bh:4 -bh:4 -bh:4 dummy.o -lxlf90 -L/usr/lpp/xlf/lib -lxlopt -lxlf -lxlomp_ser -lm -lc")
set(aix_xlf_64_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
set(aix_xlf_64_dirs "/usr/lpp/xlf/lib")
list(APPEND platforms aix_xlf_64)
+list(APPEND langs Fortran)
# xlf90 -q32 dummy.f -V
set(aix_xlf90_32_text "/bin/ld -b32 /lib/crt0.o -bpT:0x10000000 -bpD:0x20000000 -bh:4 dummy.o -lxlf90 -L/usr/lpp/xlf/lib -lxlopt -lxlf -lxlomp_ser -lm -lc")
set(aix_xlf90_32_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
set(aix_xlf90_32_dirs "/usr/lpp/xlf/lib")
list(APPEND platforms aix_xlf90_32)
+list(APPEND langs Fortran)
# xlf90 -q64 dummy.f -V
set(aix_xlf90_64_text "/bin/ld -b64 /lib/crt0_64.o -bpT:0x100000000 -bpD:0x110000000 -bh:4 dummy.o -lxlf90 -L/usr/lpp/xlf/lib -lxlopt -lxlf -lxlomp_ser -lm -lc")
set(aix_xlf90_64_libs "xlf90;xlopt;xlf;xlomp_ser;m;c")
set(aix_xlf90_64_dirs "/usr/lpp/xlf/lib")
list(APPEND platforms aix_xlf90_64)
+list(APPEND langs Fortran)
# g++ dummy.c -v
set(aix_g++_text " /prefix/libexec/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/collect2 -bpT:0x10000000 -bpD:0x20000000 -btextro /lib/crt0.o /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/crtcxa.o /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/crtdbase.o -L/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0 -L/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/../../.. /tmp//ccKROJ1f.o -lstdc++ -lm -lgcc_s /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a -lc -lgcc_s /prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a")
set(aix_g++_libs "stdc++;m;gcc_s;/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a;c;gcc_s;/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0/libgcc.a")
set(aix_g++_dirs "/prefix/lib/gcc/powerpc-ibm-aix7.2.0.0/7.2.0;/prefix/lib")
list(APPEND platforms aix_g++)
+list(APPEND langs CXX)
#-----------------------------------------------------------------------------
# HP
@@ -367,6 +410,7 @@ set(hp_cc_old_text "cc: LPATH is /usr/lib/pa1.1:/usr/lib:/opt/langtools/lib:
set(hp_cc_old_libs "c")
set(hp_cc_old_dirs "/usr/lib/pa1.1;/usr/lib;/opt/langtools/lib")
list(APPEND platforms hp_cc_old)
+list(APPEND langs C)
# aCC dummy.cxx -v
set(hp_aCC_old_text "LPATH=/usr/lib/pa1.1:/usr/lib:/opt/langtools/lib
@@ -374,6 +418,7 @@ set(hp_aCC_old_text "LPATH=/usr/lib/pa1.1:/usr/lib:/opt/langtools/lib
set(hp_aCC_old_libs "std;stream;Csup;m;cl;c")
set(hp_aCC_old_dirs "/usr/lib/pa1.1;/usr/lib;/opt/langtools/lib;/opt/aCC/lib")
list(APPEND platforms hp_aCC_old)
+list(APPEND langs CXX)
# cc dummy.c -v
set(hp_cc_32_text "LPATH=/usr/lib/hpux32:/opt/langtools/lib/hpux32
@@ -381,6 +426,7 @@ set(hp_cc_32_text "LPATH=/usr/lib/hpux32:/opt/langtools/lib/hpux32
set(hp_cc_32_libs "c")
set(hp_cc_32_dirs "/usr/lib/hpux32;/opt/langtools/lib/hpux32")
list(APPEND platforms hp_cc_32)
+list(APPEND langs C)
# cc +DD64 dummy.c -v
set(hp_cc_64_text "LPATH=/usr/lib/hpux64:/opt/langtools/lib/hpux64
@@ -388,6 +434,7 @@ set(hp_cc_64_text "LPATH=/usr/lib/hpux64:/opt/langtools/lib/hpux64
set(hp_cc_64_libs "c")
set(hp_cc_64_dirs "/usr/lib/hpux64;/opt/langtools/lib/hpux64")
list(APPEND platforms hp_cc_64)
+list(APPEND langs C)
# aCC dummy.cxx -v
set(hp_aCC_32_text "LPATH=/usr/lib/hpux32:/opt/langtools/lib/hpux32
@@ -395,6 +442,7 @@ set(hp_aCC_32_text "LPATH=/usr/lib/hpux32:/opt/langtools/lib/hpux32
set(hp_aCC_32_libs "std_v2;Csup;m;unwind;Csup;c;dl")
set(hp_aCC_32_dirs "/usr/lib/hpux32;/opt/langtools/lib/hpux32;/opt/aCC/lib/hpux32")
list(APPEND platforms hp_aCC_32)
+list(APPEND langs CXX)
# aCC +DD64 dummy.cxx -v
set(hp_aCC_64_text "LPATH=/usr/lib/hpux64:/opt/langtools/lib/hpux64
@@ -402,6 +450,7 @@ set(hp_aCC_64_text "LPATH=/usr/lib/hpux64:/opt/langtools/lib/hpux64
set(hp_aCC_64_libs "std_v2;Csup;m;unwind;Csup;c;dl")
set(hp_aCC_64_dirs "/usr/lib/hpux64;/opt/langtools/lib/hpux64;/opt/aCC/lib/hpux64")
list(APPEND platforms hp_aCC_64)
+list(APPEND langs CXX)
# f90 dummy.f -v
set(hp_f90_32_text "LPATH is: /usr/lib/hpux32/:/opt/langtools/lib/hpux32/
@@ -409,6 +458,7 @@ set(hp_f90_32_text "LPATH is: /usr/lib/hpux32/:/opt/langtools/lib/hpux32/
set(hp_f90_32_libs "-l:libF90.a;-l:libIO77.a;m;c;unwind;uca")
set(hp_f90_32_dirs "/usr/lib/hpux32;/opt/langtools/lib/hpux32")
list(APPEND platforms hp_f90_32)
+list(APPEND langs Fortran)
# f90 +DD64 dummy.f -v
set(hp_f90_64_text "LPATH is: /usr/lib/hpux64/:/opt/langtools/lib/hpux64/
@@ -416,6 +466,7 @@ set(hp_f90_64_text "LPATH is: /usr/lib/hpux64/:/opt/langtools/lib/hpux64/
set(hp_f90_64_libs "-l:libF90.a;-l:libIO77.a;m;c;unwind;uca")
set(hp_f90_64_dirs "/usr/lib/hpux64;/opt/langtools/lib/hpux64")
list(APPEND platforms hp_f90_64)
+list(APPEND langs Fortran)
#-----------------------------------------------------------------------------
# Cygwin
@@ -425,12 +476,14 @@ set(cygwin_gcc_text " /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe -Bdynamic -
set(cygwin_gcc_libs "gcc;cygwin;user32;kernel32;advapi32;shell32;gcc")
set(cygwin_gcc_dirs "/usr/lib/gcc/i686-pc-cygwin/3.4.4;/usr/lib")
list(APPEND platforms cygwin_gcc)
+list(APPEND langs C)
# g++ dummy.cxx -v
set(cygwin_g++_text " /usr/lib/gcc/i686-pc-cygwin/3.4.4/collect2.exe -Bdynamic --dll-search-prefix=cyg /usr/lib/gcc/i686-pc-cygwin/3.4.4/../../../crt0.o -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4 -L/usr/lib/gcc/i686-pc-cygwin/3.4.4/../../.. /home/user/AppData/Local/Temp/ccsvcDO6.o -lstdc++ -lgcc -lcygwin -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc")
set(cygwin_g++_libs "stdc++;gcc;cygwin;user32;kernel32;advapi32;shell32;gcc")
set(cygwin_g++_dirs "/usr/lib/gcc/i686-pc-cygwin/3.4.4;/usr/lib")
list(APPEND platforms cygwin_g++)
+list(APPEND langs CXX)
# gfortran dummy.f -v
set(cygwin_gfortran_text "Configured with: ... LD=/opt/gcc-tools/bin/ld.exe
@@ -439,6 +492,7 @@ set(cygwin_gfortran_text "Configured with: ... LD=/opt/gcc-tools/bin/ld.exe
set(cygwin_gfortran_libs "gfortranbegin;gfortran;gcc_s;gcc_s;gcc;cygwin;user32;kernel32;advapi32;shell32;gcc_s;gcc_s;gcc")
set(cygwin_gfortran_dirs "/usr/lib/gcc/i686-pc-cygwin/4.3.2;/usr/lib")
list(APPEND platforms cygwin_gfortran)
+list(APPEND langs Fortran)
#-----------------------------------------------------------------------------
# MSYS
@@ -448,18 +502,21 @@ set(msys_gcc_text " C:/some-mingw/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe
set(msys_gcc_libs "mingw32;gcc;moldname;mingwex;user32;kernel32;advapi32;shell32;mingw32;gcc;moldname;mingwex")
set(msys_gcc_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/some-mingw/lib;C:/some-mingw/lib")
list(APPEND platforms msys_gcc)
+list(APPEND langs C)
# g++ dummy.cxx -v
set(msys_g++_text " C:/some-mingw/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic /some-mingw/lib/crt2.o C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5 -LC:/some-mingw/bin/../lib/gcc -L/some-mingw/lib -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/../../.. C:/home/user/AppData/Local/Temp/cci5hYPk.o -lstdc++ -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtend.o")
set(msys_g++_libs "stdc++;mingw32;gcc;moldname;mingwex;user32;kernel32;advapi32;shell32;mingw32;gcc;moldname;mingwex")
set(msys_g++_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/some-mingw/lib;C:/some-mingw/lib")
list(APPEND platforms msys_g++)
+list(APPEND langs CXX)
# g77 dummy.f -v
set(msys_g77_text " C:/some-mingw/bin/../libexec/gcc/mingw32/3.4.5/collect2.exe -Bdynamic /some-mingw/lib/crt2.o C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtbegin.o -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5 -LC:/some-mingw/bin/../lib/gcc -L/some-mingw/lib -LC:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/../../.. C:/home/user/AppData/Local/Temp/ccabRxQ1.o -lfrtbegin -lg2c -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvapi32 -lshell32 -lmingw32 -lgcc -lmoldname -lmingwex -lmsvcrt C:/some-mingw/bin/../lib/gcc/mingw32/3.4.5/crtend.o")
set(msys_g77_libs "frtbegin;g2c;mingw32;gcc;moldname;mingwex;user32;kernel32;advapi32;shell32;mingw32;gcc;moldname;mingwex")
set(msys_g77_dirs "C:/some-mingw/lib/gcc/mingw32/3.4.5;C:/some-mingw/lib/gcc;/some-mingw/lib;C:/some-mingw/lib")
list(APPEND platforms msys_g77)
+list(APPEND langs Fortran)
#-----------------------------------------------------------------------------
# MSYS2-runtime
@@ -469,18 +526,21 @@ set(msys2rt_gcc_text " /usr/lib/gcc/i686-pc-msys/6.4.0/collect2.exe -Bdynamic --
set(msys2rt_gcc_libs "msys-2.0;user32;kernel32;advapi32;shell32")
set(msys2rt_gcc_dirs "/usr/lib/gcc/i686-pc-msys/6.4.0;/usr/lib")
list(APPEND platforms msysrt_gcc)
+list(APPEND langs C)
# g++ dummy.cxx -v
set(msys2rt_g++_text " /usr/lib/gcc/i686-pc-msys/6.4.0/collect2.exe -Bdynamic --dll-search-prefix=msys- /usr/lib/gcc/i686-pc-msys/6.4.0/../../../crt0.o -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0/../../.. /home/user/AppData/Local/Temp/ccsvcDO6.o -lstdc++ -lgcc -lmsys-2.0 -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc")
set(msys2rt_g++_libs "stdc++;msys-2.0;user32;kernel32;advapi32;shell32")
set(msys2rt_g++_dirs "/usr/lib/gcc/i686-pc-msys/6.4.0;/usr/lib")
list(APPEND platforms msysrt_g++)
+list(APPEND langs CXX)
# g77 dummy.f -v
set(msys2rt_g77_text "Configured with: ... LD=/opt/gcc-tools/bin/ld.exe /usr/lib/gcc/i686-pc-msys/6.4.0/collect2.exe -Bdynamic --dll-search-prefix=msys- -u ___register_frame_info -u ___deregister_frame_info /usr/lib/gcc/i686-pc-msys/6.4.0/../../../crt0.o /usr/lib/gcc/i686-pc-msys/6.4.0/crtbegin.o -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0 -L/usr/lib/gcc/i686-pc-msys/6.4.0/../../.. /home/user/AppData/Local/Temp/ccqRWKWg.o -lgfortranbegin -lgfortran -lgcc_s -lgcc_s -lgcc -lmsys-2.0 -luser32 -lkernel32 -ladvapi32 -lshell32 -lgcc_s -lgcc_s -lgcc /usr/lib/gcc/i686-pc-msys/6.4.0/crtend.o")
set(msys2rt_g77_libs "stdc++;msys-2.0;user32;kernel32;advapi32;shell32")
set(msys2rt_g77_dirs "/usr/lib/gcc/i686-pc-msys/6.4.0;/usr/lib")
list(APPEND platforms msysrt_g77)
+list(APPEND langs Fortran)
#-----------------------------------------------------------------------------
# MSYS2-mingw
@@ -490,18 +550,21 @@ set(msys2_gcc_text " C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/c
set(msys2_gcc_libs "mingw32;gcc;moldname;mingwex;pthread;advapi32;shell32;user32;kernel32;mingw32;gcc;moldname;mingwex")
set(msys2_gcc_dirs "C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0;C:/msys64/mingw64/lib/gcc;C:/msys64/mingw64/x86_64-w64-mingw32/lib;C:/msys64/mingw64/lib")
list(APPEND platforms msys2_gcc)
+list(APPEND langs C)
# g++ dummy.cxx -v
set(msys2_g++_text " C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/collect2.exe -plugin C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/liblto_plugin-0.dll -plugin-opt=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:/msys64/tmp/ccJQgvbN.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -m i386pep -Bdynamic C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtbegin.o -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0 -LC:/msys64/mingw64/bin/../lib/gcc -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../.. C:/msys64/tmp/ccqPpuVS.o -lstdc++ -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/default-manifest.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtend.o")
set(msys2_g++_libs "stdc++;mingw32;gcc_s;gcc;moldname;mingwex;pthread;advapi32;shell32;user32;kernel32;mingw32;gcc_s;gcc;moldname;mingwex")
set(msys2_g++_dirs "C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0;C:/msys64/mingw64/lib/gcc;C:/msys64/mingw64/x86_64-w64-mingw32/lib;C:/msys64/mingw64/lib")
list(APPEND platforms msys2_g++)
+list(APPEND langs CXX)
# gfortran dummy.f90 -v
set(msys2_gfortran_text " C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/collect2.exe -plugin C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/liblto_plugin-0.dll -plugin-opt=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/lto-wrapper.exe -plugin-opt=-fresolution=C:/msys64/tmp/cczOKIDy.res -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lquadmath -plugin-opt=-pass-through=-lm -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -plugin-opt=-pass-through=-lpthread -plugin-opt=-pass-through=-ladvapi32 -plugin-opt=-pass-through=-lshell32 -plugin-opt=-pass-through=-luser32 -plugin-opt=-pass-through=-lkernel32 -plugin-opt=-pass-through=-lmingw32 -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lmoldname -plugin-opt=-pass-through=-lmingwex -plugin-opt=-pass-through=-lmsvcrt -m i386pep -Bdynamic C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/crt2.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtbegin.o -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0 -LC:/msys64/mingw64/bin/../lib/gcc -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib -LC:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../.. C:/msys64/tmp/ccyXuCgD.o -lgfortran -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt -lquadmath -lm -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt -lpthread -ladvapi32 -lshell32 -luser32 -lkernel32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/../../../../x86_64-w64-mingw32/lib/../lib/default-manifest.o C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.2.0/crtend.o")
set(msys2_gfortran_libs "gfortran;mingw32;gcc_s;gcc;moldname;mingwex;quadmath;m;mingw32;gcc_s;gcc;moldname;mingwex;pthread;advapi32;shell32;user32;kernel32;mingw32;gcc_s;gcc;moldname;mingwex")
set(msys2_gfortran_dirs "C:/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/7.2.0;C:/msys64/mingw64/lib/gcc;C:/msys64/mingw64/x86_64-w64-mingw32/lib;C:/msys64/mingw64/lib")
list(APPEND platforms msys2_gfortran)
+list(APPEND langs Fortran)
#-----------------------------------------------------------------------------
# MSVC from NVIDIA CUDA
@@ -510,6 +573,18 @@ set(nvcc_msvc_text [[cuda-fake-ld cl.exe -nologo "tmp/a_dlink.obj" "tmp/CMakeCUD
set(nvcc_msvc_libs "cudadevrt.lib;cudart_static.lib")
set(nvcc_msvc_dirs "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/x64")
list(APPEND platforms nvcc_msvc)
+list(APPEND langs CUDA)
+
+#-----------------------------------------------------------------------------
+# MSVC from NVIDIA CUDA custom compiler
+
+set(nvcc_msvc_cl_text [[cuda-fake-ld cl -nologo "tmp/a_dlink.obj" "tmp/CMakeCUDACompilerId.obj" -link -INCREMENTAL:NO "/LIBPATH:C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/bin/../lib/x64" cudadevrt.lib cudart_static.lib -Fe"a.exe"]])
+set(nvcc_msvc_cl_libs "cudadevrt.lib;cudart_static.lib")
+set(nvcc_msvc_cl_dirs "C:/Program Files/NVIDIA GPU Computing Toolkit/CUDA/v8.0/lib/x64")
+set(nvcc_msvc_cl_compiler_id NVIDIA)
+set(nvcc_msvc_cl_compiler_sim_id MSVC)
+list(APPEND platforms nvcc_msvc_cl)
+list(APPEND langs CUDA)
#-----------------------------------------------------------------------------
# PGI on Windows
@@ -527,6 +602,7 @@ set(windows_pgf95_startfile "pgimain[mx][xpt]+[.]obj")
set(windows_pgf95_libs "libpgmp;pg;libpgf90rtl;libpgf90;libpgf90_rpm1;libpgf902;libpgf90rtl;libpgftnrtl;libpgc14;libnspgc;legacy_stdio_definitions;oldnames")
set(windows_pgf95_dirs "X:/NOT-PROGRAM-FILES-86/Microsoft Visual Studio 14.0/VC/Lib/AMD64;X:/NOT-PROGRAM-FILES-86/Windows Kits/10/Lib/10.0.15063.0/ucrt/x64;X:/NOT-PROGRAM-FILES-86/Windows Kits/10/Lib/10.0.15063.0/um/x64;X:/NOT-PROGRAM-FILES/PGICE/win64/17.4/lib")
list(APPEND platforms windows_pgf95)
+list(APPEND langs Fortran)
# pgf77 dummy.f77 -v
set(windows_pgf77_text [[Writing to file C:\temp\pgf776eC42buYRoCNJk.lnk
@@ -537,6 +613,7 @@ set(windows_pgf77_startfile "pgimain[mx][xpt]+[.]obj")
set(windows_pgf77_libs "libpgmp;libpgftnrtl;libpgc14;libnspgc;legacy_stdio_definitions;oldnames")
set(windows_pgf77_dirs "X:/NOT-PROGRAM-FILES-86/Microsoft Visual Studio 14.0/VC/Lib/AMD64;X:/NOT-PROGRAM-FILES-86/Windows Kits/10/Lib/10.0.15063.0/ucrt/x64;X:/NOT-PROGRAM-FILES-86/Windows Kits/10/Lib/10.0.15063.0/um/x64;X:/NOT-PROGRAM-FILES/PGICE/win64/17.4/lib")
list(APPEND platforms windows_pgf77)
+list(APPEND langs Fortran)
# pgcc dummy.c -v
set(windows_pgcc_text [[Writing to file C:\temp\pgcc6esqW26_ZNKyL.lnk
@@ -547,6 +624,7 @@ set(windows_pgcc_startfile "pgimain[mx][xpt]+[.]obj")
set(windows_pgcc_libs "libpgmp;libpgc14;libnspgc;legacy_stdio_definitions;oldnames")
set(windows_pgcc_dirs "X:/NOT-PROGRAM-FILES-86/Microsoft Visual Studio 14.0/VC/Lib/AMD64;X:/NOT-PROGRAM-FILES-86/Windows Kits/10/Lib/10.0.15063.0/ucrt/x64;X:/NOT-PROGRAM-FILES-86/Windows Kits/10/Lib/10.0.15063.0/um/x64;X:/NOT-PROGRAM-FILES/PGICE/win64/17.4/lib")
list(APPEND platforms windows_pgcc)
+list(APPEND langs C)
endif()
@@ -554,13 +632,20 @@ endif()
# Test parsing for all above examples.
set(CMAKE_LINKER "not-a-linker[]().*+^$?")
-foreach(p IN LISTS platforms)
+foreach(p lang IN ZIP_LISTS platforms langs)
if(DEFINED ${p}_startfile)
set(CMAKE_LINK_STARTFILE "${${p}_startfile}")
else()
unset(CMAKE_LINK_STARTFILE)
endif()
- cmake_parse_implicit_link_info("${${p}_text}" libs dirs fwks log "${${p}_obj_regex}")
+ if(DEFINED ${p}_compiler_id)
+ set(CMAKE_${lang}_ID ${${p}_compiler_id})
+ endif()
+ if(DEFINED ${p}_compiler_sim_id)
+ set(CMAKE_${lang}_SIMULATE_ID ${${p}_compiler_sim_id})
+ endif()
+
+ cmake_parse_implicit_link_info("${${p}_text}" libs dirs fwks log "${${p}_obj_regex}" LANGUAGE ${lang})
foreach(v libs dirs fwks)
if(DEFINED "${p}_${v}" AND NOT "${${v}}" STREQUAL "${${p}_${v}}")
diff --git a/Tests/CTestCoverageCollectGCOV/test.cmake.in b/Tests/CTestCoverageCollectGCOV/test.cmake.in
index a36f374..7c7a3e5 100644
--- a/Tests/CTestCoverageCollectGCOV/test.cmake.in
+++ b/Tests/CTestCoverageCollectGCOV/test.cmake.in
@@ -34,9 +34,10 @@ set(expected_out
# then back to relative to get them in canonical form (or maybe this is a bug
# in how the tarball is generated?)
function(to_relative_paths real_paths paths)
+ file(REAL_PATH "${CTEST_BINARY_DIRECTORY}" base)
foreach(file ${paths})
- file(REAL_PATH "${file}" real_path BASE_DIRECTORY "${CTEST_BINARY_DIRECTORY}")
- file(RELATIVE_PATH relative_path "${CTEST_BINARY_DIRECTORY}" "${real_path}")
+ file(REAL_PATH "${file}" real_path BASE_DIRECTORY "${base}")
+ file(RELATIVE_PATH relative_path "${base}" "${real_path}")
list(APPEND local_real_paths "${relative_path}")
message(DEBUG "${file} -> ${real_path} -> ${relative_path}")
endforeach()
diff --git a/Tests/CTestTestFdSetSize/sleep.c b/Tests/CTestTestFdSetSize/sleep.c
index 2fb6490..d55cec6 100644
--- a/Tests/CTestTestFdSetSize/sleep.c
+++ b/Tests/CTestTestFdSetSize/sleep.c
@@ -1,7 +1,11 @@
#if defined(_WIN32)
# include <windows.h>
-#else
+#elif _XOPEN_SOURCE >= 500 || defined(_ALL_SOURCE)
# include <unistd.h>
+#else
+# include <time.h>
+
+# include <sys/select.h>
#endif
/* sleeps for 0.1 second */
@@ -9,8 +13,14 @@ int main(int argc, char** argv)
{
#if defined(_WIN32)
Sleep(100);
-#else
+#elif _XOPEN_SOURCE >= 500 || defined(_ALL_SOURCE)
usleep(100 * 1000);
+#else
+ struct timeval tv;
+ tv.tv_sec = 0;
+ tv.tv_usec = 100 * 1000;
+
+ select(0, NULL, NULL, NULL, &tv);
#endif
return 0;
}
diff --git a/Tests/CompileFeatures/CMakeLists.txt b/Tests/CompileFeatures/CMakeLists.txt
index c6d1e8a..f3d3a73 100644
--- a/Tests/CompileFeatures/CMakeLists.txt
+++ b/Tests/CompileFeatures/CMakeLists.txt
@@ -356,6 +356,7 @@ else()
HAVE_CXX_STD_17=$<COMPILE_FEATURES:cxx_std_17>
HAVE_CXX_STD_20=$<COMPILE_FEATURES:cxx_std_20>
HAVE_CXX_STD_23=$<COMPILE_FEATURES:cxx_std_23>
+ HAVE_CXX_STD_26=$<COMPILE_FEATURES:cxx_std_26>
)
endif()
diff --git a/Tests/CompileFeatures/genex_test.cpp b/Tests/CompileFeatures/genex_test.cpp
index 9c3910e..048f3de 100644
--- a/Tests/CompileFeatures/genex_test.cpp
+++ b/Tests/CompileFeatures/genex_test.cpp
@@ -27,6 +27,9 @@
# if HAVE_CXX_STD_23 && !defined(ALLOW_LATER_STANDARDS)
# error HAVE_CXX_STD_23 is true with CXX_STANDARD == 11
# endif
+# if HAVE_CXX_STD_26 && !defined(ALLOW_LATER_STANDARDS)
+# error HAVE_CXX_STD_26 is true with CXX_STANDARD == 11
+# endif
#endif
#if !HAVE_OVERRIDE_CONTROL
diff --git a/Tests/Complex/CMakeLists.txt b/Tests/Complex/CMakeLists.txt
index 5df22d2..9493a2f 100644
--- a/Tests/Complex/CMakeLists.txt
+++ b/Tests/Complex/CMakeLists.txt
@@ -5,6 +5,14 @@ cmake_minimum_required(VERSION 2.4)
cmake_policy(SET CMP0054 NEW)
project (Complex)
+# Inform the test if the debug configuration is getting built.
+string(APPEND CMAKE_C_FLAGS_RELEASE " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_RELEASE " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_C_FLAGS_MINSIZEREL " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL " -DCOMPLEX_NDEBUG")
+
# Test that renaming a built-in works when configured multiple times.
message("message")
function(message)
diff --git a/Tests/Complex/Executable/complex.cxx b/Tests/Complex/Executable/complex.cxx
index 49e97d5..67a1645 100644
--- a/Tests/Complex/Executable/complex.cxx
+++ b/Tests/Complex/Executable/complex.cxx
@@ -62,7 +62,7 @@ void cmPassed(const char* Message, const char* m2 = "")
# error This is a problem. Looks like ADD_DEFINITIONS and REMOVE_DEFINITIONS does not work
#endif
-#if defined(NDEBUG) && !defined(CMAKE_IS_FUN_IN_RELEASE_MODE)
+#if defined(COMPLEX_NDEBUG) && !defined(CMAKE_IS_FUN_IN_RELEASE_MODE)
# error Per-configuration directory-level definition not inherited.
#endif
diff --git a/Tests/ComplexOneConfig/CMakeLists.txt b/Tests/ComplexOneConfig/CMakeLists.txt
index 5a4134d..e4fdc68 100644
--- a/Tests/ComplexOneConfig/CMakeLists.txt
+++ b/Tests/ComplexOneConfig/CMakeLists.txt
@@ -5,6 +5,14 @@ cmake_minimum_required(VERSION 2.4)
cmake_policy(SET CMP0054 NEW)
project (Complex)
+# Inform the test if the debug configuration is getting built.
+string(APPEND CMAKE_C_FLAGS_RELEASE " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_RELEASE " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_C_FLAGS_MINSIZEREL " -DCOMPLEX_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL " -DCOMPLEX_NDEBUG")
+
# Try setting a new policy. The IF test is for coverage.
if(POLICY CMP0003)
cmake_policy(SET CMP0003 NEW)
diff --git a/Tests/ComplexOneConfig/Executable/complex.cxx b/Tests/ComplexOneConfig/Executable/complex.cxx
index 54c18f4..097668b 100644
--- a/Tests/ComplexOneConfig/Executable/complex.cxx
+++ b/Tests/ComplexOneConfig/Executable/complex.cxx
@@ -62,7 +62,7 @@ void cmPassed(const char* Message, const char* m2 = "")
# error This is a problem. Looks like ADD_DEFINITIONS and REMOVE_DEFINITIONS does not work
#endif
-#if defined(NDEBUG) && !defined(CMAKE_IS_FUN_IN_RELEASE_MODE)
+#if defined(COMPLEX_NDEBUG) && !defined(CMAKE_IS_FUN_IN_RELEASE_MODE)
# error Per-configuration directory-level definition not inherited.
#endif
diff --git a/Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt b/Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt
index 97670e3..447e137 100644
--- a/Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt
+++ b/Tests/Cuda/SeparableCompCXXOnly/CMakeLists.txt
@@ -1,3 +1,6 @@
-project(SeparableCompCXXOnly LANGUAGES CXX CUDA)
+# Set CMAKE_CUDA_SEPARABLE_COMPILATION before `project`
+# so we verify that compiler/linker verbose extraction
+# works as required when a `dlink` is part of it
set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
+project(SeparableCompCXXOnly LANGUAGES CXX CUDA)
add_executable(SeparableCompCXXOnly main.cpp)
diff --git a/Tests/CudaOnly/CMakeLists.txt b/Tests/CudaOnly/CMakeLists.txt
index aa4755d..d23e929 100644
--- a/Tests/CudaOnly/CMakeLists.txt
+++ b/Tests/CudaOnly/CMakeLists.txt
@@ -7,7 +7,6 @@ endmacro ()
add_cuda_test_macro(CudaOnly.Architecture Architecture)
add_cuda_test_macro(CudaOnly.ArchSpecial CudaOnlyArchSpecial)
add_cuda_test_macro(CudaOnly.CompileFlags CudaOnlyCompileFlags)
-
add_cuda_test_macro(CudaOnly.EnableStandard CudaOnlyEnableStandard)
add_cuda_test_macro(CudaOnly.ExportPTX CudaOnlyExportPTX)
add_cuda_test_macro(CudaOnly.SharedRuntimePlusToolkit CudaOnlySharedRuntimePlusToolkit)
@@ -28,6 +27,21 @@ if(CMake_TEST_CUDA AND NOT CMake_TEST_CUDA STREQUAL "Clang")
add_cuda_test_macro(CudaOnly.GPUDebugFlag CudaOnlyGPUDebugFlag)
endif()
+if(NOT WIN32)
+ # The CUDA only ships the shared version of the toolkit libraries
+ # on windows
+ add_cuda_test_macro(CudaOnly.StaticRuntimePlusToolkit CudaOnlyStaticRuntimePlusToolkit)
+ # `isystem` behaves differently on windows with nvcc
+ add_cuda_test_macro(CudaOnly.ToolkitIsSystemInclude CudaOnlySystemInclude)
+endif()
+
+add_cuda_test_macro(CudaOnly.DeviceLTO CudaOnlyDeviceLTO)
+
+if(MSVC)
+ # Tests for features that only work with MSVC
+ add_cuda_test_macro(CudaOnly.PDB CudaOnlyPDB)
+endif()
+
add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
@@ -41,16 +55,6 @@ add_test(NAME CudaOnly.DontResolveDeviceSymbols COMMAND
set_property(TEST "CudaOnly.DontResolveDeviceSymbols" APPEND
PROPERTY LABELS "CUDA")
-# The CUDA only ships the shared version of the toolkit libraries
-# on windows
-if(NOT WIN32)
- add_cuda_test_macro(CudaOnly.StaticRuntimePlusToolkit CudaOnlyStaticRuntimePlusToolkit)
-endif()
-
-if(MSVC)
- add_cuda_test_macro(CudaOnly.PDB CudaOnlyPDB)
-endif()
-
add_test(NAME CudaOnly.RuntimeControls COMMAND
${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
--build-and-test
diff --git a/Tests/CudaOnly/DeviceLTO/CMakeLists.txt b/Tests/CudaOnly/DeviceLTO/CMakeLists.txt
new file mode 100644
index 0000000..653b35d
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/CMakeLists.txt
@@ -0,0 +1,37 @@
+cmake_minimum_required(VERSION 3.18)
+project(DeviceLTO CUDA)
+
+# Goal:
+# Verify that we correctly compile with device LTO
+# Verify that device LTO requirements are propagated to
+# the final device link line
+
+add_library(CUDA_dlto STATIC file1.cu file2.cu file3.cu)
+add_executable(CudaOnlyDeviceLTO main.cu)
+
+set_target_properties(CUDA_dlto
+ PROPERTIES
+ CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES_ALL}"
+ CUDA_SEPARABLE_COMPILATION ON
+ POSITION_INDEPENDENT_CODE ON)
+
+set_target_properties(CudaOnlyDeviceLTO
+ PROPERTIES
+ CUDA_SEPARABLE_COMPILATION ON
+ CUDA_ARCHITECTURES "${CMAKE_CUDA_ARCHITECTURES_ALL}"
+ )
+
+target_link_libraries(CudaOnlyDeviceLTO PRIVATE CUDA_dlto)
+
+include(CheckIPOSupported)
+check_ipo_supported(LANGUAGES CUDA RESULT ipo_supported)
+if(ipo_supported)
+ set_target_properties(CUDA_dlto
+ PROPERTIES
+ INTERPROCEDURAL_OPTIMIZATION ON)
+
+ # When non-LTO variants (i.e. virtual) are built together with LTO ones the
+ # linker warns about missing device LTO for the virtual architectures.
+ # Ignore these warnings.
+ target_link_options(CudaOnlyDeviceLTO PRIVATE "$<DEVICE_LINK:-w>")
+endif()
diff --git a/Tests/CudaOnly/DeviceLTO/file1.cu b/Tests/CudaOnly/DeviceLTO/file1.cu
new file mode 100644
index 0000000..703927c
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/file1.cu
@@ -0,0 +1,17 @@
+#ifdef _WIN32
+# define EXPORT __declspec(dllexport)
+#else
+# define EXPORT
+#endif
+
+extern __device__ int file2_func(int);
+void __global__ kernel(int x)
+{
+ file2_func(x);
+}
+
+EXPORT int launch_kernel(int x)
+{
+ kernel<<<1, 1>>>(x);
+ return x;
+}
diff --git a/Tests/CudaOnly/DeviceLTO/file2.cu b/Tests/CudaOnly/DeviceLTO/file2.cu
new file mode 100644
index 0000000..73d6468
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/file2.cu
@@ -0,0 +1,5 @@
+extern __device__ int file3_func(int);
+int __device__ file2_func(int x)
+{
+ return x + file3_func(x);
+}
diff --git a/Tests/CudaOnly/DeviceLTO/file3.cu b/Tests/CudaOnly/DeviceLTO/file3.cu
new file mode 100644
index 0000000..235ac06
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/file3.cu
@@ -0,0 +1,4 @@
+int __device__ file3_func(int x)
+{
+ return x * x * x;
+}
diff --git a/Tests/CudaOnly/DeviceLTO/main.cu b/Tests/CudaOnly/DeviceLTO/main.cu
new file mode 100644
index 0000000..8ef4873
--- /dev/null
+++ b/Tests/CudaOnly/DeviceLTO/main.cu
@@ -0,0 +1,62 @@
+#include <iostream>
+
+#include "cuda.h"
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+#else
+# define IMPORT
+#endif
+
+IMPORT int launch_kernel(int x);
+
+int choose_cuda_device()
+{
+ int nDevices = 0;
+ cudaError_t err = cudaGetDeviceCount(&nDevices);
+ if (err != cudaSuccess) {
+ std::cerr << "Failed to retrieve the number of CUDA enabled devices"
+ << std::endl;
+ return 1;
+ }
+ for (int i = 0; i < nDevices; ++i) {
+ cudaDeviceProp prop;
+ cudaError_t err = cudaGetDeviceProperties(&prop, i);
+ if (err != cudaSuccess) {
+ std::cerr << "Could not retrieve properties from CUDA device " << i
+ << std::endl;
+ return 1;
+ }
+ std::cout << "prop.major: " << prop.major << std::endl;
+ err = cudaSetDevice(i);
+ if (err != cudaSuccess) {
+ std::cout << "Could not select CUDA device " << i << std::endl;
+ } else {
+ return 0;
+ }
+ }
+
+ std::cout << "Could not find a CUDA enabled card" << std::endl;
+
+ return 1;
+}
+
+int main()
+{
+ int ret = choose_cuda_device();
+ if (ret) {
+ return 0;
+ }
+
+ cudaError_t err;
+ launch_kernel(1);
+ err = cudaGetLastError();
+ if (err != cudaSuccess) {
+ std::cerr << "launch_kernel: kernel launch should have passed.\n "
+ "Error message: "
+ << cudaGetErrorString(err) << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Tests/CudaOnly/ToolkitIsSystemInclude/CMakeLists.txt b/Tests/CudaOnly/ToolkitIsSystemInclude/CMakeLists.txt
new file mode 100644
index 0000000..bc347dd
--- /dev/null
+++ b/Tests/CudaOnly/ToolkitIsSystemInclude/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.24)
+project(ToolkitIsSystemInclude CUDA)
+
+# Verify that the nvrtc.h that is inside `CMAKE_CURRENT_SOURCE_DIR` is still
+# the first include for `.cu` files.
+add_executable(CudaOnlySystemInclude main.cu)
+target_include_directories(CudaOnlySystemInclude SYSTEM PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include)
diff --git a/Tests/CudaOnly/ToolkitIsSystemInclude/include/nvrtc.h b/Tests/CudaOnly/ToolkitIsSystemInclude/include/nvrtc.h
new file mode 100644
index 0000000..5a015c4
--- /dev/null
+++ b/Tests/CudaOnly/ToolkitIsSystemInclude/include/nvrtc.h
@@ -0,0 +1,5 @@
+#define CMAKE_CUDA_TOOLKIT_IS_SYSTEM 1
+
+int main()
+{
+}
diff --git a/Tests/CudaOnly/ToolkitIsSystemInclude/main.cu b/Tests/CudaOnly/ToolkitIsSystemInclude/main.cu
new file mode 100644
index 0000000..6cff8a1
--- /dev/null
+++ b/Tests/CudaOnly/ToolkitIsSystemInclude/main.cu
@@ -0,0 +1,4 @@
+#include "nvrtc.h"
+#ifndef CMAKE_CUDA_TOOLKIT_IS_SYSTEM
+# error "Failed to specify the CUDA Toolkit includes as system"
+#endif
diff --git a/Tests/ExportImport/Export/CMakeLists.txt b/Tests/ExportImport/Export/CMakeLists.txt
index c9e41f5..6f19c13 100644
--- a/Tests/ExportImport/Export/CMakeLists.txt
+++ b/Tests/ExportImport/Export/CMakeLists.txt
@@ -155,6 +155,15 @@ target_include_directories(testInterfaceIncludeUser
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/testInterfaceIncludeUser>"
)
set_property(TARGET testInterfaceIncludeUser PROPERTY IMPORTED_NO_SYSTEM 1)
+
+add_library(testInterfaceIncludeUser2 INTERFACE)
+target_include_directories(testInterfaceIncludeUser2
+ INTERFACE
+ "$<INSTALL_INTERFACE:include/testInterfaceIncludeUser>"
+ "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/testInterfaceIncludeUser>"
+)
+set_property(TARGET testInterfaceIncludeUser2 PROPERTY EXPORT_NO_SYSTEM 1)
+
install(
FILES
"${CMAKE_CURRENT_SOURCE_DIR}/include/testInterfaceIncludeUser/testInterfaceInclude.h"
@@ -562,6 +571,7 @@ install(
TopDirLib SubDirLinkA
systemlib
testInterfaceIncludeUser
+ testInterfaceIncludeUser2
EXPORT exp
RUNTIME DESTINATION $<1:bin>$<0:/wrong>
LIBRARY DESTINATION $<1:lib>$<0:/wrong> NAMELINK_SKIP
@@ -622,6 +632,7 @@ export(TARGETS testExe1 testLib1 testLib2 testLib3
TopDirLib SubDirLinkA
systemlib
testInterfaceIncludeUser
+ testInterfaceIncludeUser2
NAMESPACE bld_
FILE ExportBuildTree.cmake
)
diff --git a/Tests/ExportImport/Import/A/CMakeLists.txt b/Tests/ExportImport/Import/A/CMakeLists.txt
index 272c7a9..5bafdf8 100644
--- a/Tests/ExportImport/Import/A/CMakeLists.txt
+++ b/Tests/ExportImport/Import/A/CMakeLists.txt
@@ -75,6 +75,10 @@ add_library(imp_testInterfaceInclude1 STATIC imp_testInterfaceInclude1.c)
target_include_directories(imp_testInterfaceInclude1 SYSTEM PRIVATE testInterfaceIncludeSystem)
target_link_libraries(imp_testInterfaceInclude1 PRIVATE exp_testInterfaceIncludeUser)
+add_library(imp_testInterfaceInclude1b STATIC imp_testInterfaceInclude1.c)
+target_include_directories(imp_testInterfaceInclude1b SYSTEM PRIVATE testInterfaceIncludeSystem)
+target_link_libraries(imp_testInterfaceInclude1b PRIVATE exp_testInterfaceIncludeUser2)
+
add_executable(imp_UseSharedLibWithHelper1 ../../../InterfaceLinkLibrariesDirect/UseSharedLibWithHelper.c)
target_link_libraries(imp_UseSharedLibWithHelper1 PRIVATE exp_testSharedLibWithHelper testSharedLibHelperExclude)
@@ -122,9 +126,13 @@ target_link_libraries(imp_testExe1b
bld_testStaticLibWithPlugin
)
-add_library(imp_testInterfaceInclude1b STATIC imp_testInterfaceInclude1.c)
-target_include_directories(imp_testInterfaceInclude1b SYSTEM PRIVATE testInterfaceIncludeSystem)
-target_link_libraries(imp_testInterfaceInclude1b PRIVATE bld_testInterfaceIncludeUser)
+add_library(imp_testInterfaceInclude1c STATIC imp_testInterfaceInclude1.c)
+target_include_directories(imp_testInterfaceInclude1c SYSTEM PRIVATE testInterfaceIncludeSystem)
+target_link_libraries(imp_testInterfaceInclude1c PRIVATE bld_testInterfaceIncludeUser)
+
+add_library(imp_testInterfaceInclude1d STATIC imp_testInterfaceInclude1.c)
+target_include_directories(imp_testInterfaceInclude1d SYSTEM PRIVATE testInterfaceIncludeSystem)
+target_link_libraries(imp_testInterfaceInclude1d PRIVATE bld_testInterfaceIncludeUser2)
add_custom_target(check_testLib1_genex ALL
COMMAND ${CMAKE_COMMAND} -DtestLib1=$<TARGET_FILE:exp_testLib1>
diff --git a/Tests/ExternalProject/CMakeLists.txt b/Tests/ExternalProject/CMakeLists.txt
index e4c6c66..81d31e7 100644
--- a/Tests/ExternalProject/CMakeLists.txt
+++ b/Tests/ExternalProject/CMakeLists.txt
@@ -45,7 +45,11 @@ if(NOT DEFINED EP_TEST_HG OR EP_TEST_HG)
find_package(Hg)
endif()
if(NOT DEFINED EP_TEST_HG AND Hg_FOUND)
- set(EP_TEST_HG 1)
+ # Check if hg executable is working
+ execute_process(COMMAND "${HG_EXECUTABLE}" --version OUTPUT_QUIET ERROR_QUIET RESULT_VARIABLE HG_RV)
+ if(HG_RV EQUAL 0)
+ set(EP_TEST_HG 1)
+ endif()
endif()
message(STATUS "EP_TEST_CVS='${EP_TEST_CVS}' CVS_EXECUTABLE='${CVS_EXECUTABLE}'")
diff --git a/Tests/FindOpenAL/CMakeLists.txt b/Tests/FindOpenAL/CMakeLists.txt
new file mode 100644
index 0000000..fc4803e
--- /dev/null
+++ b/Tests/FindOpenAL/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindOpenAL.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindOpenAL/Test"
+ "${CMake_BINARY_DIR}/Tests/FindOpenAL/Test"
+ ${build_generator_args}
+ --build-project TestFindOpenAL
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindOpenAL/Test/CMakeLists.txt b/Tests/FindOpenAL/Test/CMakeLists.txt
new file mode 100644
index 0000000..fa3e263
--- /dev/null
+++ b/Tests/FindOpenAL/Test/CMakeLists.txt
@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 3.21)
+project(TestFindOpenAL CXX)
+include(CTest)
+
+find_package(OpenAL REQUIRED)
+
+add_executable(test_tgt main.cxx)
+target_link_libraries(test_tgt OpenAL::OpenAL)
+add_test(NAME test_tgt COMMAND test_tgt)
+
+add_executable(test_var main.cxx)
+target_include_directories(test_var PRIVATE ${OPENAL_INCLUDE_DIR})
+target_link_libraries(test_var PRIVATE ${OPENAL_LIBRARY})
+add_test(NAME test_var COMMAND test_var)
diff --git a/Tests/FindOpenAL/Test/main.cxx b/Tests/FindOpenAL/Test/main.cxx
new file mode 100644
index 0000000..bb45faf
--- /dev/null
+++ b/Tests/FindOpenAL/Test/main.cxx
@@ -0,0 +1,13 @@
+#include <AL/al.h>
+#include <AL/alc.h>
+#include <stdio.h>
+
+int main()
+{
+ /* Reference an AL symbol without requiring a context at runtime. */
+ printf("&alGetString = %p\n", &alGetString);
+
+ /* Reference an ALC symbol without requiring a context at runtime. */
+ printf("&alcGetString = %p\n", &alcGetString);
+ return 0;
+}
diff --git a/Tests/FindOpenSP/CMakeLists.txt b/Tests/FindOpenSP/CMakeLists.txt
new file mode 100644
index 0000000..26826d3
--- /dev/null
+++ b/Tests/FindOpenSP/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindOpenSP.Test COMMAND
+ ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+ --build-and-test
+ "${CMake_SOURCE_DIR}/Tests/FindOpenSP/Test"
+ "${CMake_BINARY_DIR}/Tests/FindOpenSP/Test"
+ ${build_generator_args}
+ --build-project TestFindOpenSP
+ --build-options ${build_options}
+ --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+ )
diff --git a/Tests/FindOpenSP/Test/CMakeLists.txt b/Tests/FindOpenSP/Test/CMakeLists.txt
new file mode 100644
index 0000000..d8992d9
--- /dev/null
+++ b/Tests/FindOpenSP/Test/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.4)
+project(TestFindOpenSP CXX)
+include(CTest)
+
+find_package(OpenSP REQUIRED)
+
+add_definitions(-DSP_MULTI_BYTE="${OpenSP_MULTI_BYTE}")
+
+add_executable(test_tgt main.cxx)
+target_link_libraries(test_tgt OpenSP::OpenSP)
+add_test(NAME test_tgt COMMAND test_tgt)
+
+add_executable(test_var main.cxx)
+target_include_directories(test_var PRIVATE ${OpenSP_INCLUDE_DIRS})
+target_link_libraries(test_var PRIVATE ${OpenSP_LIBRARIES})
+add_test(NAME test_var COMMAND test_var)
diff --git a/Tests/FindOpenSP/Test/main.cxx b/Tests/FindOpenSP/Test/main.cxx
new file mode 100644
index 0000000..ef8aa2c
--- /dev/null
+++ b/Tests/FindOpenSP/Test/main.cxx
@@ -0,0 +1,55 @@
+#include <cassert>
+#include <string>
+
+#include "ParserEventGeneratorKit.h"
+
+std::string CharStringtostring(const SGMLApplication::CharString source)
+{
+ // The CharString type might have multi-byte characters if SP_MULTI_BYTE was
+ // defined
+ std::string result;
+ result.resize(source.len);
+ for (size_t i = 0; i < source.len; i++) {
+ result[i] = static_cast<char>(source.ptr[i]);
+ }
+ return result;
+}
+
+class OutlineApplication : public SGMLApplication
+{
+public:
+ OutlineApplication()
+ : depth_(0)
+ {
+ }
+ void startElement(const StartElementEvent& event)
+ {
+ for (unsigned i = 0; i < depth_; i++)
+ parsedOutput += "\t";
+ parsedOutput += CharStringtostring(event.gi);
+ depth_++;
+ }
+ void endElement(const EndElementEvent&) { depth_--; }
+ std::string parsedOutput;
+
+private:
+ unsigned depth_;
+};
+
+int main()
+{
+ std::string expectedOutput = "TESTDOC\tTESTELEMENT";
+ char file_name[] = "test.sgml";
+ char* files[] = { file_name, 0 };
+
+ ParserEventGeneratorKit parserKit;
+ EventGenerator* egp = parserKit.makeEventGenerator(1, files);
+ OutlineApplication app;
+ unsigned nErrors = egp->run(app);
+
+ assert(nErrors == 0);
+ assert(app.parsedOutput.compare(expectedOutput) == 0);
+
+ delete egp;
+ return 0;
+}
diff --git a/Tests/FindOpenSP/Test/test.sgml b/Tests/FindOpenSP/Test/test.sgml
new file mode 100644
index 0000000..bbf0da6
--- /dev/null
+++ b/Tests/FindOpenSP/Test/test.sgml
@@ -0,0 +1,7 @@
+ <!DOCTYPE TESTDOC [
+<!ELEMENT TESTDOC - - (TESTELEMENT)+>
+<!ELEMENT TESTELEMENT - - (#PCDATA)>
+]>
+<TESTDOC>
+<TESTELEMENT>Hello</TESTELEMENT>
+</TESTDOC>
diff --git a/Tests/FindPackageTest/CMakeLists.txt b/Tests/FindPackageTest/CMakeLists.txt
index c25b2c3..e4143b9 100644
--- a/Tests/FindPackageTest/CMakeLists.txt
+++ b/Tests/FindPackageTest/CMakeLists.txt
@@ -20,7 +20,7 @@ find_package(OpenGL QUIET)
find_package(NotAPackage QUIET)
# Look for a package that has an advanced find module.
-find_package(VTK QUIET)
+find_package(Boost QUIET)
add_executable(FindPackageTest FindPackageTest.cxx)
diff --git a/Tests/FindVulkan/Test/CMakeLists.txt b/Tests/FindVulkan/Test/CMakeLists.txt
index 42543ac..dfcfc15 100644
--- a/Tests/FindVulkan/Test/CMakeLists.txt
+++ b/Tests/FindVulkan/Test/CMakeLists.txt
@@ -7,7 +7,10 @@ set(components
glslang
shaderc_combined
SPIRV-Tools
+ volk
+ dxc
)
+
if(APPLE)
list(APPEND components MoltenVK)
endif()
@@ -75,6 +78,14 @@ if(APPLE)
add_test(NAME test_tgt_MoltenVK COMMAND test_tgt_MoltenVK)
endif()
+add_executable(test_tgt_volk main-volk.cxx)
+target_link_libraries(test_tgt_volk Vulkan::volk)
+add_test(NAME test_tgt_volk COMMAND test_tgt_volk)
+
+add_executable(test_tgt_dxc_lib main-dxc_lib.cxx)
+target_link_libraries(test_tgt_dxc_lib Vulkan::dxc_lib)
+add_test(NAME test_tgt_dxc_lib COMMAND test_tgt_dxc_lib)
+
if(Vulkan_GLSLC_EXECUTABLE)
add_test(NAME test_glslc
COMMAND ${CMAKE_COMMAND}
@@ -92,3 +103,12 @@ if(Vulkan_GLSLANG_VALIDATOR_EXECUTABLE)
-P "${CMAKE_CURRENT_LIST_DIR}/Run-glslangValidator.cmake"
)
endif()
+
+if(Vulkan_dxc_EXECUTABLE)
+ add_test(NAME test_dxc_exe
+ COMMAND ${CMAKE_COMMAND}
+ "-DVULKAN_DXC_EXECUTABLE=${Vulkan_dxc_EXECUTABLE}"
+ "-DVULKAN_DXC_EXECUTABLE_TARGET=$<TARGET_FILE:Vulkan::dxc_exe>"
+ -P "${CMAKE_CURRENT_LIST_DIR}/Run-dxc_exe.cmake"
+ )
+endif()
diff --git a/Tests/FindVulkan/Test/Run-dxc_exe.cmake b/Tests/FindVulkan/Test/Run-dxc_exe.cmake
new file mode 100644
index 0000000..0d38855
--- /dev/null
+++ b/Tests/FindVulkan/Test/Run-dxc_exe.cmake
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.12)
+
+function(run_dxc_exe exe exe_display)
+ execute_process(COMMAND ${exe} --help
+ OUTPUT_VARIABLE output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ RESULT_VARIABLE result
+ )
+
+ if(NOT result EQUAL 0)
+ message(SEND_ERROR "Result of ${exe_display} --help is ${result}, should be 0")
+ endif()
+
+ if(NOT output MATCHES "^OVERVIEW: HLSL Compiler for ")
+ message(SEND_ERROR "Output of ${exe_display} --help is \"${output}\", should begin with \"OVERVIEW: HLSL Compiler for \"")
+ endif()
+endfunction()
+
+run_dxc_exe("${VULKAN_DXC_EXECUTABLE}" "\${VULKAN_DXC_EXECUTABLE}")
+run_dxc_exe("${VULKAN_DXC_EXECUTABLE_TARGET}" "Vulkan::dxc_exe")
diff --git a/Tests/FindVulkan/Test/main-dxc_lib.cxx b/Tests/FindVulkan/Test/main-dxc_lib.cxx
new file mode 100644
index 0000000..6ccb0de
--- /dev/null
+++ b/Tests/FindVulkan/Test/main-dxc_lib.cxx
@@ -0,0 +1,23 @@
+#include <cstdio>
+
+#include "dxc/dxcapi.h"
+#include "printf.h"
+
+int main()
+{
+ IDxcCompiler3* compiler;
+ DxcCreateInstance(CLSID_DxcCompiler, IID_PPV_ARGS(&compiler));
+
+ assert(compiler);
+
+ IDxcVersionInfo* version;
+ compiler->QueryInterface(&version);
+
+ uint32_t major, minor;
+ version->GetVersion(&major, &minor);
+ printf("DirectX Shader Compiler: %u.%u\n", major, minor);
+ version->Release();
+ compiler->Release();
+
+ return 0;
+}
diff --git a/Tests/FindVulkan/Test/main-volk.cxx b/Tests/FindVulkan/Test/main-volk.cxx
new file mode 100644
index 0000000..2ec9fb4
--- /dev/null
+++ b/Tests/FindVulkan/Test/main-volk.cxx
@@ -0,0 +1,14 @@
+#include <iostream>
+
+#include <volk/volk.h>
+
+int main()
+{
+ if (volkInitialize() != VK_SUCCESS) {
+ std::cout << "volk initialization success!" << std::endl;
+ } else {
+ std::cout << "volk initialization failure!" << std::endl;
+ }
+
+ return 0;
+}
diff --git a/Tests/FortranModules/Submodules/CMakeLists.txt b/Tests/FortranModules/Submodules/CMakeLists.txt
index ab8e0f9..783af7e 100644
--- a/Tests/FortranModules/Submodules/CMakeLists.txt
+++ b/Tests/FortranModules/Submodules/CMakeLists.txt
@@ -16,6 +16,7 @@
add_executable(submod
main.f90
parent.f90
+ obfuscated_parent.f90
child.f90
grandchild.f90
greatgrandchild.f90
diff --git a/Tests/FortranModules/Submodules/main.f90 b/Tests/FortranModules/Submodules/main.f90
index 3cd2989..67ffba8 100644
--- a/Tests/FortranModules/Submodules/main.f90
+++ b/Tests/FortranModules/Submodules/main.f90
@@ -1,7 +1,10 @@
program main
use parent, only : child_function,grandchild_subroutine
use parent, only : sibling_function,GreatGrandChild_subroutine
+ ! Using a module without postfix
+ use obfuscated_parent
implicit none
- if (child_function()) call grandchild_subroutine
- if (sibling_function()) call GreatGrandChild_subroutine
+ if (child_function()) call grandchild_subroutine
+ if (sibling_function()) call GreatGrandChild_subroutine
+ if (child_function_obf()) call grandchild_subroutine_obf
end program
diff --git a/Tests/FortranModules/Submodules/obfuscated_parent.f90 b/Tests/FortranModules/Submodules/obfuscated_parent.f90
new file mode 100644
index 0000000..f3e68be
--- /dev/null
+++ b/Tests/FortranModules/Submodules/obfuscated_parent.f90
@@ -0,0 +1,33 @@
+! This module has two procedures from the "parent" module
+! but it has different combinations 'module <word>' phrases
+! in breaked lines for test of modules dependencies detection
+
+! Module declaration on breaked line with reminder
+module &
+ obfuscated_parent; implicit none
+
+ interface
+
+ ! Boolean module function
+ module logical &
+ function child_function_obf() result(child_stuff)
+ end function
+
+ ! Module subroutine
+ module subroutine &
+ grandchild_subroutine_obf()
+ end subroutine
+
+ end interface
+
+ contains
+
+ module logical function child_function_obf() result(child_stuff)
+ child_stuff=.true.
+ end function
+
+ module subroutine grandchild_subroutine_obf()
+ print *,"Test passed."
+ end subroutine
+
+end module obfuscated_parent
diff --git a/Tests/FortranModules/test_module_main.f90 b/Tests/FortranModules/test_module_main.f90
index 6ac97fa..958d0a2 100644
--- a/Tests/FortranModules/test_module_main.f90
+++ b/Tests/FortranModules/test_module_main.f90
@@ -1,4 +1,4 @@
PROGRAM MAINF90
- USE TEST_MODULE
+ USE TEST_MODULE, only : TEST_MODULE_FUNCTION
PRINT *,'Sum is',TEST_MODULE_FUNCTION(1., 2.)
END PROGRAM MAINF90
diff --git a/Tests/FunctionTest/CMakeLists.txt b/Tests/FunctionTest/CMakeLists.txt
index 6450447..0660d0f 100644
--- a/Tests/FunctionTest/CMakeLists.txt
+++ b/Tests/FunctionTest/CMakeLists.txt
@@ -51,7 +51,7 @@ track_find_variable(testvar is_changed)
if ("${is_changed}" STREQUAL changed)
pass("same argument name test")
else ()
- pass("same argument name test")
+ fail("same argument name test" "Got: ${is_changed}")
endif ()
include("Util.cmake")
@@ -59,7 +59,7 @@ tester()
if (tester_res STREQUAL "${CMAKE_CURRENT_LIST_FILE}")
pass("CMAKE_CURRENT_LIST_FILE test")
else ()
- pass("CMAKE_CURRENT_LIST_FILE test")
+ fail("CMAKE_CURRENT_LIST_FILE test" "Got: ${tester_res}")
endif ()
diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt
index bb4b92c..e82cea2 100644
--- a/Tests/IncludeDirectories/CMakeLists.txt
+++ b/Tests/IncludeDirectories/CMakeLists.txt
@@ -121,12 +121,66 @@ add_library(ordertest ordertest.cpp)
target_include_directories(ordertest SYSTEM PUBLIC SystemIncludeDirectories/systemlib)
target_include_directories(ordertest PUBLIC SystemIncludeDirectories/userlib)
+# Test "IMPORTED_NO_SYSTEM" property and its interaction with "SYSTEM"
add_library(ordertest2 ordertest.cpp)
target_include_directories(ordertest2 SYSTEM PRIVATE SystemIncludeDirectories/systemlib)
target_link_libraries(ordertest2 PRIVATE ordertest2_userlib)
add_library(ordertest2_userlib INTERFACE IMPORTED)
target_include_directories(ordertest2_userlib INTERFACE SystemIncludeDirectories/userlib)
set_property(TARGET ordertest2_userlib PROPERTY IMPORTED_NO_SYSTEM 1)
+get_property(system_prop_value TARGET ordertest2_userlib PROPERTY SYSTEM)
+if (NOT system_prop_value)
+ message(SEND_ERROR "ordertest2_userlib SYSTEM property should be ON.")
+endif()
+
+# Test "SYSTEM" property of non-imported libraries
+add_library(ordertest3_systemlib INTERFACE)
+target_include_directories(ordertest3_systemlib INTERFACE SystemIncludeDirectories/systemlib)
+set_property(TARGET ordertest3_systemlib PROPERTY SYSTEM 1)
+add_library(ordertest3_userlib INTERFACE)
+target_include_directories(ordertest3_userlib INTERFACE SystemIncludeDirectories/userlib)
+add_library(ordertest3 ordertest.cpp)
+target_link_libraries(ordertest3 PRIVATE ordertest3_systemlib ordertest3_userlib)
+
+# Test "SYSTEM" property of imported libraries and its interaction with "IMPORTED_NO_SYSTEM"
+add_library(ordertest4 ordertest.cpp)
+target_include_directories(ordertest4 SYSTEM PRIVATE SystemIncludeDirectories/systemlib)
+target_link_libraries(ordertest4 PRIVATE ordertest4_userlib)
+add_library(ordertest4_userlib INTERFACE IMPORTED)
+target_include_directories(ordertest4_userlib INTERFACE SystemIncludeDirectories/userlib)
+set_property(TARGET ordertest4_userlib PROPERTY SYSTEM 0)
+get_property(imported_no_system_prop_value TARGET ordertest4_userlib PROPERTY IMPORTED_NO_SYSTEM)
+if (imported_no_system_prop_value)
+ message(SEND_ERROR "ordertest4_userlib IMPORTED_NO_SYSTEM property should be OFF.")
+endif()
+
+# Test the interaction between "SYSTEM" and "INTERFACE_SYSTEM_INCLUDE_DIRECTORIES"
+add_library(ordertest5_systemlib INTERFACE)
+target_include_directories(ordertest5_systemlib SYSTEM INTERFACE SystemIncludeDirectories/systemlib)
+# The default value of `SYSTEM` is already `OFF`. Here we explicitly set it again.
+set_property(TARGET ordertest5_systemlib PROPERTY SYSTEM 0)
+add_library(ordertest5_userlib INTERFACE)
+target_include_directories(ordertest5_userlib INTERFACE SystemIncludeDirectories/userlib)
+add_library(ordertest5 ordertest.cpp)
+target_link_libraries(ordertest5 PRIVATE ordertest5_systemlib ordertest5_userlib)
+
+# Test that the include of imported executable is treated as system by default.
+add_executable(ordertest6_systemexe IMPORTED)
+target_include_directories(ordertest6_systemexe INTERFACE SystemIncludeDirectories/systemlib)
+set_property(TARGET ordertest6_systemexe PROPERTY ENABLE_EXPORTS 1)
+add_library(ordertest6_userlib INTERFACE)
+target_include_directories(ordertest6_userlib INTERFACE SystemIncludeDirectories/userlib)
+add_library(ordertest6 ordertest.cpp)
+target_link_libraries(ordertest6 PRIVATE ordertest6_systemexe ordertest6_userlib)
+
+# Test that the include of imported executable is not treated as system if "SYSTEM" property is OFF.
+add_library(ordertest7 ordertest.cpp)
+target_include_directories(ordertest7 SYSTEM PRIVATE SystemIncludeDirectories/systemlib)
+target_link_libraries(ordertest7 PRIVATE ordertest7_userexe)
+add_library(ordertest7_userexe INTERFACE IMPORTED)
+target_include_directories(ordertest7_userexe INTERFACE SystemIncludeDirectories/userlib)
+set_property(TARGET ordertest7_userexe PROPERTY ENABLE_EXPORTS 1)
+set_property(TARGET ordertest7_userexe PROPERTY SYSTEM 0)
add_subdirectory(StandardIncludeDirectories)
add_subdirectory(TargetIncludeDirectories)
diff --git a/Tests/LoadCommand/CMakeCommands/cmTestCommand.c b/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
index af7b092..7176ebe 100644
--- a/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
+++ b/Tests/LoadCommand/CMakeCommands/cmTestCommand.c
@@ -75,10 +75,10 @@ static int CCONV InitialPass(void* inf, void* mf, int argc, char* argv[])
info->CAPI->DisplaySatus(mf, info->CAPI->GetStartOutputDirectory(mf));
info->CAPI->DisplaySatus(mf, info->CAPI->GetCurrentDirectory(mf));
info->CAPI->DisplaySatus(mf, info->CAPI->GetCurrentOutputDirectory(mf));
- sprintf(buffer, "Cache version: %d.%d, CMake version: %d.%d",
- info->CAPI->GetCacheMajorVersion(mf),
- info->CAPI->GetCacheMinorVersion(mf),
- info->CAPI->GetMajorVersion(mf), info->CAPI->GetMinorVersion(mf));
+ snprintf(
+ buffer, sizeof(buffer), "Cache version: %d.%d, CMake version: %d.%d",
+ info->CAPI->GetCacheMajorVersion(mf), info->CAPI->GetCacheMinorVersion(mf),
+ info->CAPI->GetMajorVersion(mf), info->CAPI->GetMinorVersion(mf));
info->CAPI->DisplaySatus(mf, buffer);
if (info->CAPI->CommandExists(mf, "SET")) {
info->CAPI->DisplaySatus(mf, "Command SET exists");
@@ -91,10 +91,12 @@ static int CCONV InitialPass(void* inf, void* mf, int argc, char* argv[])
source_file = info->CAPI->CreateNewSourceFile(mf);
cstr = info->CAPI->SourceFileGetSourceName(source_file);
- sprintf(buffer, "Should be empty (source file name): [%s]", cstr);
+ snprintf(buffer, sizeof(buffer), "Should be empty (source file name): [%s]",
+ cstr);
info->CAPI->DisplaySatus(mf, buffer);
cstr = info->CAPI->SourceFileGetFullPath(source_file);
- sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
+ snprintf(buffer, sizeof(buffer),
+ "Should be empty (source file full path): [%s]", cstr);
info->CAPI->DisplaySatus(mf, buffer);
info->CAPI->DefineSourceFileProperty(mf, "SOME_PROPERTY", "unused old prop",
"This property is no longer used", 0);
@@ -106,7 +108,8 @@ static int CCONV InitialPass(void* inf, void* mf, int argc, char* argv[])
"This property is for testing.", 0);
info->CAPI->SourceFileSetProperty(source_file, "SOME_PROPERTY2", "HERE");
cstr = info->CAPI->SourceFileGetProperty(source_file, "ABSTRACT");
- sprintf(buffer, "Should be 0 (source file abstract property): [%p]", cstr);
+ snprintf(buffer, sizeof(buffer),
+ "Should be 0 (source file abstract property): [%p]", cstr);
info->CAPI->DisplaySatus(mf, buffer);
info->CAPI->DestroySourceFile(source_file);
diff --git a/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c b/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
index af7b092..7176ebe 100644
--- a/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
+++ b/Tests/LoadCommandOneConfig/CMakeCommands/cmTestCommand.c
@@ -75,10 +75,10 @@ static int CCONV InitialPass(void* inf, void* mf, int argc, char* argv[])
info->CAPI->DisplaySatus(mf, info->CAPI->GetStartOutputDirectory(mf));
info->CAPI->DisplaySatus(mf, info->CAPI->GetCurrentDirectory(mf));
info->CAPI->DisplaySatus(mf, info->CAPI->GetCurrentOutputDirectory(mf));
- sprintf(buffer, "Cache version: %d.%d, CMake version: %d.%d",
- info->CAPI->GetCacheMajorVersion(mf),
- info->CAPI->GetCacheMinorVersion(mf),
- info->CAPI->GetMajorVersion(mf), info->CAPI->GetMinorVersion(mf));
+ snprintf(
+ buffer, sizeof(buffer), "Cache version: %d.%d, CMake version: %d.%d",
+ info->CAPI->GetCacheMajorVersion(mf), info->CAPI->GetCacheMinorVersion(mf),
+ info->CAPI->GetMajorVersion(mf), info->CAPI->GetMinorVersion(mf));
info->CAPI->DisplaySatus(mf, buffer);
if (info->CAPI->CommandExists(mf, "SET")) {
info->CAPI->DisplaySatus(mf, "Command SET exists");
@@ -91,10 +91,12 @@ static int CCONV InitialPass(void* inf, void* mf, int argc, char* argv[])
source_file = info->CAPI->CreateNewSourceFile(mf);
cstr = info->CAPI->SourceFileGetSourceName(source_file);
- sprintf(buffer, "Should be empty (source file name): [%s]", cstr);
+ snprintf(buffer, sizeof(buffer), "Should be empty (source file name): [%s]",
+ cstr);
info->CAPI->DisplaySatus(mf, buffer);
cstr = info->CAPI->SourceFileGetFullPath(source_file);
- sprintf(buffer, "Should be empty (source file full path): [%s]", cstr);
+ snprintf(buffer, sizeof(buffer),
+ "Should be empty (source file full path): [%s]", cstr);
info->CAPI->DisplaySatus(mf, buffer);
info->CAPI->DefineSourceFileProperty(mf, "SOME_PROPERTY", "unused old prop",
"This property is no longer used", 0);
@@ -106,7 +108,8 @@ static int CCONV InitialPass(void* inf, void* mf, int argc, char* argv[])
"This property is for testing.", 0);
info->CAPI->SourceFileSetProperty(source_file, "SOME_PROPERTY2", "HERE");
cstr = info->CAPI->SourceFileGetProperty(source_file, "ABSTRACT");
- sprintf(buffer, "Should be 0 (source file abstract property): [%p]", cstr);
+ snprintf(buffer, sizeof(buffer),
+ "Should be 0 (source file abstract property): [%p]", cstr);
info->CAPI->DisplaySatus(mf, buffer);
info->CAPI->DestroySourceFile(source_file);
diff --git a/Tests/Module/CheckIPOSupported-CUDA/CMakeLists.txt b/Tests/Module/CheckIPOSupported-CUDA/CMakeLists.txt
new file mode 100644
index 0000000..9dd670e
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CUDA/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.8)
+project(CheckIPOSupported-CUDA LANGUAGES CUDA)
+
+cmake_policy(SET CMP0069 NEW)
+
+include(CheckIPOSupported)
+check_ipo_supported(RESULT ipo_supported OUTPUT ipo_output)
+if(ipo_supported)
+ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
+endif()
+
+if(NOT ipo_supported AND CMAKE_CUDA_COMPILER_ID STREQUAL "NVIDIA"
+ AND CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 11.2)
+ message(FATAL_ERROR "CheckIPOSupported failed to correctly identify NVIDIA CUDA IPO support")
+endif()
+
+set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
+
+add_library(foo STATIC foo.cu)
+set_target_properties(foo PROPERTIES
+ WINDOWS_EXPORT_ALL_SYMBOLS ON
+ POSITION_INDEPENDENT_CODE ON)
+
+add_library(bar SHARED bar.cu)
+set_target_properties(bar PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON)
+target_link_libraries(bar PRIVATE foo)
+
+add_executable(CheckIPOSupported-CUDA main.cu)
+target_link_libraries(CheckIPOSupported-CUDA PUBLIC bar)
+
+enable_testing()
+add_test(NAME CheckIPOSupported-CUDA COMMAND CheckIPOSupported-CUDA)
diff --git a/Tests/Module/CheckIPOSupported-CUDA/bar.cu b/Tests/Module/CheckIPOSupported-CUDA/bar.cu
new file mode 100644
index 0000000..79b276d
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CUDA/bar.cu
@@ -0,0 +1,12 @@
+__device__ int foo_func(int);
+
+void __global__ bar_kernel(int x)
+{
+ foo_func(x);
+}
+
+int launch_kernel(int x)
+{
+ bar_kernel<<<1, 1>>>(x);
+ return x;
+}
diff --git a/Tests/Module/CheckIPOSupported-CUDA/foo.cu b/Tests/Module/CheckIPOSupported-CUDA/foo.cu
new file mode 100644
index 0000000..416607b
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CUDA/foo.cu
@@ -0,0 +1,4 @@
+extern __device__ int foo_func(int a)
+{
+ return a * 42 + 9;
+}
diff --git a/Tests/Module/CheckIPOSupported-CUDA/main.cu b/Tests/Module/CheckIPOSupported-CUDA/main.cu
new file mode 100644
index 0000000..8ef4873
--- /dev/null
+++ b/Tests/Module/CheckIPOSupported-CUDA/main.cu
@@ -0,0 +1,62 @@
+#include <iostream>
+
+#include "cuda.h"
+
+#ifdef _WIN32
+# define IMPORT __declspec(dllimport)
+#else
+# define IMPORT
+#endif
+
+IMPORT int launch_kernel(int x);
+
+int choose_cuda_device()
+{
+ int nDevices = 0;
+ cudaError_t err = cudaGetDeviceCount(&nDevices);
+ if (err != cudaSuccess) {
+ std::cerr << "Failed to retrieve the number of CUDA enabled devices"
+ << std::endl;
+ return 1;
+ }
+ for (int i = 0; i < nDevices; ++i) {
+ cudaDeviceProp prop;
+ cudaError_t err = cudaGetDeviceProperties(&prop, i);
+ if (err != cudaSuccess) {
+ std::cerr << "Could not retrieve properties from CUDA device " << i
+ << std::endl;
+ return 1;
+ }
+ std::cout << "prop.major: " << prop.major << std::endl;
+ err = cudaSetDevice(i);
+ if (err != cudaSuccess) {
+ std::cout << "Could not select CUDA device " << i << std::endl;
+ } else {
+ return 0;
+ }
+ }
+
+ std::cout << "Could not find a CUDA enabled card" << std::endl;
+
+ return 1;
+}
+
+int main()
+{
+ int ret = choose_cuda_device();
+ if (ret) {
+ return 0;
+ }
+
+ cudaError_t err;
+ launch_kernel(1);
+ err = cudaGetLastError();
+ if (err != cudaSuccess) {
+ std::cerr << "launch_kernel: kernel launch should have passed.\n "
+ "Error message: "
+ << cudaGetErrorString(err) << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Tests/ModuleDefinition/CMakeLists.txt b/Tests/ModuleDefinition/CMakeLists.txt
index 567fb4b..483bd8b 100644
--- a/Tests/ModuleDefinition/CMakeLists.txt
+++ b/Tests/ModuleDefinition/CMakeLists.txt
@@ -15,7 +15,17 @@ add_custom_command(OUTPUT example_dll_gen.def
add_library(example_dll_gen SHARED example_dll_gen.c example_dll_gen.def)
# Test /DEF:<file> flag recognition for VS.
-if(MSVC OR CMAKE_C_COMPILER_ID STREQUAL "Intel")
+if(MSVC AND CMAKE_C_COMPILER_ID STREQUAL "IntelLLVM")
+ # IntelLLVM for MSVC frontend variant needs the /DEF flag wrapped to be sent
+ # to the linker, which happens automatically when the DEF file is added
+ # to the sources.
+ add_library(example_dll_2 SHARED
+ example_dll_2.c
+ "${ModuleDefinition_SOURCE_DIR}/example_dll_2.def"
+ )
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS EXAMPLE_DLL_2)
+ set(example_dll_2 example_dll_2)
+elseif(MSVC OR CMAKE_C_COMPILER_ID STREQUAL "Intel")
add_library(example_dll_2 SHARED example_dll_2.c)
set_property(TARGET example_dll_2 PROPERTY LINK_FLAGS
/DEF:"${ModuleDefinition_SOURCE_DIR}/example_dll_2.def")
diff --git a/Tests/Preprocess/CMakeLists.txt b/Tests/Preprocess/CMakeLists.txt
index 4347459..84ca5e8 100644
--- a/Tests/Preprocess/CMakeLists.txt
+++ b/Tests/Preprocess/CMakeLists.txt
@@ -197,9 +197,14 @@ endif()
#-----------------------------------------------------------------------------
# Inform the test if the debug configuration is getting built.
-# The NDEBUG definition takes care of this for release.
string(APPEND CMAKE_C_FLAGS_DEBUG " -DPREPROCESS_DEBUG")
string(APPEND CMAKE_CXX_FLAGS_DEBUG " -DPREPROCESS_DEBUG")
+string(APPEND CMAKE_C_FLAGS_RELEASE " -DPREPROCESS_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_RELEASE " -DPREPROCESS_NDEBUG")
+string(APPEND CMAKE_C_FLAGS_RELWITHDEBINFO " -DPREPROCESS_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_RELWITHDEBINFO " -DPREPROCESS_NDEBUG")
+string(APPEND CMAKE_C_FLAGS_MINSIZEREL " -DPREPROCESS_NDEBUG")
+string(APPEND CMAKE_CXX_FLAGS_MINSIZEREL " -DPREPROCESS_NDEBUG")
# Inform the test if it built from Xcode.
if(PP_XCODE)
diff --git a/Tests/Preprocess/preprocess.c b/Tests/Preprocess/preprocess.c
index b3117da..88f9e97 100644
--- a/Tests/Preprocess/preprocess.c
+++ b/Tests/Preprocess/preprocess.c
@@ -33,7 +33,7 @@ int check_defines_C(void)
result = 0;
}
}
-#ifdef NDEBUG
+#ifdef PREPROCESS_NDEBUG
# ifdef FILE_DEF_DEBUG
{
fprintf(stderr, "FILE_DEF_DEBUG should not be defined in C\n");
diff --git a/Tests/Preprocess/preprocess.cxx b/Tests/Preprocess/preprocess.cxx
index f2fffef..50150d1 100644
--- a/Tests/Preprocess/preprocess.cxx
+++ b/Tests/Preprocess/preprocess.cxx
@@ -35,7 +35,7 @@ int check_defines_CXX()
result = 0;
}
}
-#ifdef NDEBUG
+#ifdef PREPROCESS_NDEBUG
# ifdef FILE_DEF_DEBUG
{
fprintf(stderr, "FILE_DEF_DEBUG should not be defined in CXX\n");
diff --git a/Tests/RunCMake/AutoExportDll/AutoExport.cmake b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
index dbcf4b8..fe57d56 100644
--- a/Tests/RunCMake/AutoExportDll/AutoExport.cmake
+++ b/Tests/RunCMake/AutoExportDll/AutoExport.cmake
@@ -7,7 +7,7 @@ set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
add_library(autoexport SHARED hello.cxx world.cxx foo.c $<TARGET_OBJECTS:objlib>)
add_library(autoexport3 SHARED cppCLI.cxx)
if(MSVC AND NOT MSVC_VERSION VERSION_LESS 1600
- AND NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
+ AND NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
set_property(TARGET autoexport3 PROPERTY COMMON_LANGUAGE_RUNTIME "")
endif()
@@ -17,7 +17,7 @@ if(MSVC)
add_library(autoexport_for_exec SHARED hello2.c)
target_link_libraries(autoexport_for_exec say)
if(NOT MSVC_VERSION VERSION_LESS 1600 AND
- NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
+ NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
enable_language(ASM_MASM)
target_sources(autoexport PRIVATE nop.asm)
set_property(SOURCE nop.asm PROPERTY COMPILE_FLAGS /safeseh)
diff --git a/Tests/RunCMake/CMP0102/CMP0102-OLD-stderr.txt b/Tests/RunCMake/CMP0102/CMP0102-OLD-stderr.txt
new file mode 100644
index 0000000..5d09fcf
--- /dev/null
+++ b/Tests/RunCMake/CMP0102/CMP0102-OLD-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0102-OLD.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0102 will be removed from a future version
+ of CMake.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 09f248e..42ff450 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -305,6 +305,9 @@ add_RunCMake_test(ExportImport)
add_RunCMake_test(ExternalData)
add_RunCMake_test(FeatureSummary)
add_RunCMake_test(FPHSA)
+if(CMAKE_USE_SYSTEM_JSONCPP)
+ list(APPEND FileAPI_ARGS -DJsonCpp_VERSION_STRING=${JsonCpp_VERSION_STRING})
+endif()
add_RunCMake_test(FileAPI -DPython_EXECUTABLE=${Python_EXECUTABLE}
-DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
add_RunCMake_test(FindBoost)
@@ -453,6 +456,7 @@ add_RunCMake_test(find_path)
add_RunCMake_test(find_program -DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME})
add_RunCMake_test(foreach)
add_RunCMake_test(function)
+add_RunCMake_test(block)
add_RunCMake_test(get_filename_component)
add_RunCMake_test(get_property)
add_RunCMake_test(if)
@@ -566,6 +570,9 @@ if(CMake_TEST_CUDA)
endif()
add_RunCMake_test(DependencyGraph -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER})
+# Add C++ Module tests.
+add_RunCMake_test(CXXModules -DCMake_TEST_MODULE_COMPILATION=${CMake_TEST_MODULE_COMPILATION} -DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES})
+
# ctresalloc links against CMakeLib and CTestLib, which means it can't be built
# if CMake_TEST_EXTERNAL_CMAKE is activated (the compiler might be different.)
# So, it has to be provided in the original build tree.
@@ -967,7 +974,7 @@ endif()
if(${CMAKE_GENERATOR} MATCHES "Visual Studio ([^9]|9[0-9])")
add_RunCMake_test(CSharpCustomCommand)
- if(NOT CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
+ if(NOT CMAKE_VS_PLATFORM_NAME STREQUAL "ARM64")
add_RunCMake_test(CSharpReferenceImport)
endif()
endif()
@@ -992,6 +999,10 @@ add_RunCMake_test(CMakePresetsTest
-DPython_EXECUTABLE=${Python_EXECUTABLE}
-DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA}
)
+add_RunCMake_test(CMakePresetsPackage
+ -DPython_EXECUTABLE=${Python_EXECUTABLE}
+ -DCMake_TEST_JSON_SCHEMA=${CMake_TEST_JSON_SCHEMA}
+ )
add_RunCMake_test(VerifyHeaderSets)
diff --git a/Tests/RunCMake/CMakePresets/Comment-stderr.txt b/Tests/RunCMake/CMakePresets/Comment-stderr.txt
index 2f404bc..b3b6b66 100644
--- a/Tests/RunCMake/CMakePresets/Comment-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/Comment-stderr.txt
@@ -1,2 +1,9 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/Comment: JSON parse error$
+]*/Tests/RunCMake/CMakePresets/Comment: JSON parse error
+Errors:
+[^
+]*Comment\/CMakePresets.json:
+\* Line 1, Column 1
+ Syntax error: value, object or array expected\.
+\* Line 2, Column 1
+ Extra non-whitespace after JSON value\.$
diff --git a/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt b/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
index 6970674..0d3c500 100644
--- a/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/EmptyPresetName-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/EmptyPresetName: Invalid preset$
+]*/Tests/RunCMake/CMakePresets/EmptyPresetName: Invalid preset
+Errors:
+[^
+]*/EmptyPresetName/CMakePresets.json$
diff --git a/Tests/RunCMake/CMakePresets/GoodNoSCache.cmake b/Tests/RunCMake/CMakePresets/GoodNoSCache.cmake
index df58e72..d9e399f 100644
--- a/Tests/RunCMake/CMakePresets/GoodNoSCache.cmake
+++ b/Tests/RunCMake/CMakePresets/GoodNoSCache.cmake
@@ -1,4 +1,5 @@
include(${CMAKE_CURRENT_LIST_DIR}/TestVariable.cmake)
get_filename_component(_parent "${CMAKE_SOURCE_DIR}" DIRECTORY)
+file(REAL_PATH "${_parent}" _parent)
test_variable(CMAKE_BINARY_DIR "" "${_parent}/GoodNoSCachePrep-build")
diff --git a/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt b/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
index 7ccabab..85a2d78 100644
--- a/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/IncludeNotFound-stderr.txt
@@ -1,2 +1,5 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/IncludeNotFound: File not found$
+]*/Tests/RunCMake/CMakePresets/IncludeNotFound: File not found
+Errors:
+[^
+]*/IncludeNotFound/NotFound.json: Failed to read file$
diff --git a/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt b/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
index a43bf77..89eff9f 100644
--- a/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
+++ b/Tests/RunCMake/CMakePresets/JSONParseError-stderr.txt
@@ -1,2 +1,9 @@
^CMake Error: Could not read presets from [^
-]*/Tests/RunCMake/CMakePresets/JSONParseError: JSON parse error$
+]*/Tests/RunCMake/CMakePresets/JSONParseError: JSON parse error
+Errors:
+[^
+]*JSONParseError/CMakePresets.json:
+\* Line 1, Column 1
+ Syntax error: value, object or array expected\.
+\* Line 1, Column 1
+ A valid JSON document must be either an array or an object value\.$
diff --git a/Tests/RunCMake/CMakePresets/ListAllPresetsNoBuild-stdout.txt b/Tests/RunCMake/CMakePresets/ListAllPresetsNoBuild-stdout.txt
new file mode 100644
index 0000000..38f52aa
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/ListAllPresetsNoBuild-stdout.txt
@@ -0,0 +1,8 @@
+^Not searching for unused variables given on the command line.
+Available configure presets:
+
+ "default"
+
+Available test presets:
+
+ "default"$
diff --git a/Tests/RunCMake/CMakePresets/ListAllPresetsNoBuild.json.in b/Tests/RunCMake/CMakePresets/ListAllPresetsNoBuild.json.in
new file mode 100644
index 0000000..9259477
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/ListAllPresetsNoBuild.json.in
@@ -0,0 +1,14 @@
+{
+ "version": 3,
+ "configurePresets": [
+ {
+ "name": "default"
+ }
+ ],
+ "testPresets": [
+ {
+ "name": "default",
+ "configurePreset": "default"
+ }
+ ]
+}
diff --git a/Tests/RunCMake/CMakePresets/ListAllPresetsNoTest-stdout.txt b/Tests/RunCMake/CMakePresets/ListAllPresetsNoTest-stdout.txt
new file mode 100644
index 0000000..8cac0a8
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/ListAllPresetsNoTest-stdout.txt
@@ -0,0 +1,8 @@
+^Not searching for unused variables given on the command line.
+Available configure presets:
+
+ "default"
+
+Available build presets:
+
+ "default"$
diff --git a/Tests/RunCMake/CMakePresets/ListAllPresetsNoTest.json.in b/Tests/RunCMake/CMakePresets/ListAllPresetsNoTest.json.in
new file mode 100644
index 0000000..33fd036
--- /dev/null
+++ b/Tests/RunCMake/CMakePresets/ListAllPresetsNoTest.json.in
@@ -0,0 +1,14 @@
+{
+ "version": 3,
+ "configurePresets": [
+ {
+ "name": "default"
+ }
+ ],
+ "buildPresets": [
+ {
+ "name": "default",
+ "configurePreset": "default"
+ }
+ ]
+}
diff --git a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
index d097086..c511b34 100644
--- a/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CMakePresets/RunCMakeTest.cmake
@@ -304,6 +304,12 @@ unset(RunCMake_TEST_BINARY_DIR)
run_cmake_presets(ListPresetsNoSuchPreset)
run_cmake_presets(ListPresetsHidden)
+set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/ListAllPresetsNoBuild.json.in")
+run_cmake_presets(ListAllPresetsNoBuild --list-presets=all)
+
+set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/ListAllPresetsNoTest.json.in")
+run_cmake_presets(ListAllPresetsNoTest --list-presets=all)
+
# Test warning and error flags
set(CMakePresets_FILE "${RunCMake_SOURCE_DIR}/Warnings.json.in")
set(CMakePresets_WARN_UNUSED_CLI 1)
diff --git a/Tests/RunCMake/CMakePresetsPackage/CMakeLists.txt.in b/Tests/RunCMake/CMakePresetsPackage/CMakeLists.txt.in
new file mode 100644
index 0000000..129184a
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/CMakeLists.txt.in
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.19)
+project("@CASE_NAME@" NONE)
+include("@CASE_SOURCE_DIR@/@CASE_NAME@.cmake")
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-config-file-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-config-file-check.cmake
new file mode 100644
index 0000000..40240f9
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-config-file-check.cmake
@@ -0,0 +1,6 @@
+include("${RunCMake_TEST_BINARY_DIR}/default/CPackConfig.cmake")
+
+set(filename "${RunCMake_TEST_BINARY_DIR}/default/_CPack_Packages/${CPACK_TOPLEVEL_TAG}/TGZ/config-file-alt.tar.gz")
+if(NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "Expected ${filename} to exist but it does not")
+endif()
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-configurations-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-configurations-check.cmake
new file mode 100644
index 0000000..3d684af
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-configurations-check.cmake
@@ -0,0 +1,18 @@
+if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ include("${RunCMake_TEST_BINARY_DIR}/default/CPackConfig.cmake")
+ set(cpack_dir "${RunCMake_TEST_BINARY_DIR}/default/_CPack_Packages/${CPACK_TOPLEVEL_TAG}")
+ set(contents [[Debug
+Release
+]])
+
+ file(GLOB dirs RELATIVE "${cpack_dir}" "${cpack_dir}/*")
+ foreach(dir IN LISTS dirs)
+ set(configs_file "${cpack_dir}/${dir}/${CPACK_PACKAGE_FILE_NAME}/configs.txt")
+ file(READ "${configs_file}" actual_contents)
+ if(NOT contents STREQUAL actual_contents)
+ string(REPLACE "\n" "\n " contents_formatted "${contents}")
+ string(REPLACE "\n" "\n " actual_contents_formatted "${actual_contents}")
+ string(APPEND RunCMake_TEST_FAILED "Expected contents of ${configs_file}:\n ${contents_formatted}\nActual contents:\n ${actual_contents_formatted}\n")
+ endif()
+ endforeach()
+endif()
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-debug-stdout.txt b/Tests/RunCMake/CMakePresetsPackage/Good-package-debug-stdout.txt
new file mode 100644
index 0000000..be885b4
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-debug-stdout.txt
@@ -0,0 +1,2 @@
+CPack: [^
+]* Enable Debug
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-generators-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-generators-check.cmake
new file mode 100644
index 0000000..aaa75e4
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-generators-check.cmake
@@ -0,0 +1 @@
+check_cpack_packages("TBZ2;TXZ" "")
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-no-environment-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-no-environment-check.cmake
new file mode 100644
index 0000000..205e7b7
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-no-environment-check.cmake
@@ -0,0 +1,7 @@
+check_cpack_packages("TGZ;TXZ" [[TEST_ENV not defined
+TEST_ENV_REF=xx
+TEST_ENV_OVERRIDE not defined
+TEST_ENV_OVERRIDE_REF not defined
+]])
+
+include("${RunCMake_SOURCE_DIR}/check.cmake")
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-package-directory-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-package-directory-check.cmake
new file mode 100644
index 0000000..8f4b771
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-package-directory-check.cmake
@@ -0,0 +1,6 @@
+include("${RunCMake_TEST_BINARY_DIR}/default/CPackConfig.cmake")
+
+set(filename "${RunCMake_TEST_BINARY_DIR}/default/package-directory/_CPack_Packages/${CPACK_TOPLEVEL_TAG}/TGZ/${CPACK_PACKAGE_FILE_NAME}.tar.gz")
+if(NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "Expected ${filename} to exist but it does not")
+endif()
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-package-name-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-package-name-check.cmake
new file mode 100644
index 0000000..fdc4824
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-package-name-check.cmake
@@ -0,0 +1,7 @@
+include("${RunCMake_TEST_BINARY_DIR}/default/CPackConfig.cmake")
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/default/${CPACK_PACKAGE_FILE_NAME}.json" contents)
+string(JSON package_name GET "${contents}" packageName)
+if(NOT package_name STREQUAL "package-name")
+ set(RunCMake_TEST_FAILED "Expected package name to be \"package-name\" but it was \"${package_name}\"")
+endif()
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-package-version-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-package-version-check.cmake
new file mode 100644
index 0000000..dba9110
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-package-version-check.cmake
@@ -0,0 +1,7 @@
+include("${RunCMake_TEST_BINARY_DIR}/default/CPackConfig.cmake")
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/default/${CPACK_PACKAGE_FILE_NAME}.json" contents)
+string(JSON package_version GET "${contents}" packageVersion)
+if(NOT package_version STREQUAL "1.0")
+ set(RunCMake_TEST_FAILED "Expected package version to be \"1.0\" but it was \"${package_version}\"")
+endif()
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-variables-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-variables-check.cmake
new file mode 100644
index 0000000..2858170
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-variables-check.cmake
@@ -0,0 +1,6 @@
+include("${RunCMake_TEST_BINARY_DIR}/default/CPackConfig.cmake")
+
+set(filename "${RunCMake_TEST_BINARY_DIR}/default/_CPack_Packages/${CPACK_TOPLEVEL_TAG}/TGZ/variables-package.tar.gz")
+if(NOT EXISTS "${filename}")
+ set(RunCMake_TEST_FAILED "Expected ${filename} to exist but it does not")
+endif()
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-verbose-stdout.txt b/Tests/RunCMake/CMakePresetsPackage/Good-package-verbose-stdout.txt
new file mode 100644
index 0000000..22fd115
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-verbose-stdout.txt
@@ -0,0 +1 @@
+CPack: Enable Verbose
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good-package-with-environment-check.cmake b/Tests/RunCMake/CMakePresetsPackage/Good-package-with-environment-check.cmake
new file mode 100644
index 0000000..a775e4d
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good-package-with-environment-check.cmake
@@ -0,0 +1,7 @@
+check_cpack_packages("TGZ;TXZ" [[TEST_ENV=Environment variable
+TEST_ENV_REF=xEnvironment variablex
+TEST_ENV_OVERRIDE=Override
+TEST_ENV_OVERRIDE_REF=xOverridex
+]])
+
+include("${RunCMake_SOURCE_DIR}/check.cmake")
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good.cmake b/Tests/RunCMake/CMakePresetsPackage/Good.cmake
new file mode 100644
index 0000000..d019443
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good.cmake
@@ -0,0 +1,31 @@
+set(CPACK_PACKAGE_NAME Good)
+set(CPACK_GENERATOR "TGZ;TXZ")
+
+include(CPack)
+
+install(CODE [[
+function(print_env name)
+ if(DEFINED ENV{${name}})
+ file(APPEND $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/env.txt "${name}=$ENV{${name}}\n")
+ else()
+ file(APPEND $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/env.txt "${name} not defined\n")
+ endif()
+endfunction()
+
+file(REMOVE $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/env.txt)
+print_env(TEST_ENV)
+print_env(TEST_ENV_REF)
+print_env(TEST_ENV_OVERRIDE)
+print_env(TEST_ENV_OVERRIDE_REF)
+
+file(APPEND $ENV{DESTDIR}${CMAKE_INSTALL_PREFIX}/configs.txt "$<CONFIG>\n")
+]])
+
+file(WRITE "${CMAKE_BINARY_DIR}/CPackConfigAlt.cmake" [[include(${CMAKE_CURRENT_LIST_DIR}/CPackConfig.cmake)
+set(CPACK_PACKAGE_FILE_NAME "config-file-alt")
+]])
+
+file(WRITE "${CMAKE_BINARY_DIR}/external_package.cmake" [[if(NOT CPACK_PACKAGE_VENDOR STREQUAL "some-vendor")
+ message(FATAL_ERROR "Expected vendor to be \"some-vendor\" but it was \"${CPACK_PACKAGE_VENDOR}\"")
+endif()
+]])
diff --git a/Tests/RunCMake/CMakePresetsPackage/Good.json.in b/Tests/RunCMake/CMakePresetsPackage/Good.json.in
new file mode 100644
index 0000000..0c0e7d9
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/Good.json.in
@@ -0,0 +1,135 @@
+{
+ "version": 6,
+ "configurePresets": [
+ {
+ "name": "default",
+ "generator": "@RunCMake_GENERATOR@",
+ "binaryDir": "${sourceDir}/build/${presetName}",
+ "environment": {
+ "TEST_ENV": "Environment variable",
+ "TEST_ENV_OVERRIDE": "Overridden environment variable"
+ }
+ }
+ ],
+ "buildPresets": [
+ {
+ "name": "build-default-debug",
+ "configurePreset": "default",
+ "configuration": "Debug"
+ },
+ {
+ "name": "build-default-release",
+ "inherits": "build-default-debug",
+ "configuration": "Release"
+ }
+ ],
+ "packagePresets": [
+ {
+ "name": "minimal",
+ "configurePreset": "default"
+ },
+ {
+ "name": "defaults",
+ "hidden": false,
+ "inherits": [],
+ "vendor": {},
+ "displayName": "",
+ "description": "",
+ "environment": {},
+ "configurePreset": "default",
+ "inheritConfigureEnvironment": true
+ },
+ {
+ "name": "no-environment",
+ "configurePreset": "default",
+ "inheritConfigureEnvironment": false,
+ "environment": {
+ "TEST_ENV_REF": "x$env{TEST_ENV}x"
+ }
+ },
+ {
+ "name": "with-environment",
+ "inherits": "no-environment",
+ "inheritConfigureEnvironment": true,
+ "environment": {
+ "TEST_ENV_OVERRIDE": "Override",
+ "TEST_ENV_OVERRIDE_REF": "x$env{TEST_ENV_OVERRIDE}x",
+ "TEST_ENV_REF": "x$env{TEST_ENV}x"
+ }
+ },
+ {
+ "name": "generators",
+ "inherits": "minimal",
+ "generators": [
+ "TBZ2",
+ "TXZ"
+ ]
+ },
+ {
+ "name": "configurations",
+ "inherits": "minimal",
+ "configurations": [
+ "Debug",
+ "Release"
+ ]
+ },
+ {
+ "name": "variables",
+ "inherits": "minimal",
+ "variables": {
+ "CPACK_PACKAGE_FILE_NAME": "variables-package"
+ }
+ },
+ {
+ "name": "config-file",
+ "inherits": "minimal",
+ "configFile": "CPackConfigAlt.cmake"
+ },
+ {
+ "name": "debug",
+ "inherits": "minimal",
+ "output": {
+ "debug": true
+ }
+ },
+ {
+ "name": "verbose",
+ "inherits": "minimal",
+ "output": {
+ "verbose": true
+ }
+ },
+ {
+ "name": "package-name",
+ "inherits": "minimal",
+ "generators": [
+ "External"
+ ],
+ "packageName": "package-name"
+ },
+ {
+ "name": "package-version",
+ "inherits": "minimal",
+ "generators": [
+ "External"
+ ],
+ "packageVersion": "1.0"
+ },
+ {
+ "name": "package-directory",
+ "inherits": "minimal",
+ "packageDirectory": "${sourceDir}/build/default/package-directory"
+ },
+ {
+ "name": "vendor-name",
+ "inherits": "minimal",
+ "generators": [
+ "External"
+ ],
+ "variables": {
+ "CPACK_EXTERNAL_PACKAGE_SCRIPT": "${sourceDir}/build/default/external_package.cmake"
+ },
+ "vendorName": "some-vendor"
+ }
+ ]
+}
diff --git a/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake b/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake
new file mode 100644
index 0000000..0d5def1
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/RunCMakeTest.cmake
@@ -0,0 +1,101 @@
+include(RunCMake)
+
+# Presets do not support legacy VS generator name architecture suffix.
+if(RunCMake_GENERATOR MATCHES "^(Visual Studio [0-9]+ [0-9]+) ")
+ set(RunCMake_GENERATOR "${CMAKE_MATCH_1}")
+endif()
+
+function(run_cmake_package_presets name CMakePresetsPackage_CONFIGURE_PRESETS CMakePresetsPackage_BUILD_PRESETS CMakePresetsPackage_PACKAGE_PRESETS)
+ set(RunCMake_TEST_SOURCE_DIR "${RunCMake_BINARY_DIR}/${name}")
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_TEST_SOURCE_DIR}/build")
+ set(RunCMake_TEST_COMMAND_WORKING_DIRECTORY "${RunCMake_TEST_SOURCE_DIR}")
+
+ set(RunCMake_TEST_NO_CLEAN TRUE)
+
+ file(REMOVE_RECURSE "${RunCMake_TEST_SOURCE_DIR}")
+ file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
+
+ set(CASE_NAME "${name}")
+ set(CASE_SOURCE_DIR "${RunCMake_SOURCE_DIR}")
+ configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt.in" "${RunCMake_TEST_SOURCE_DIR}/CMakeLists.txt" @ONLY)
+
+ if(NOT CMakePresetsPackage_FILE)
+ set(CMakePresetsPackage_FILE "${RunCMake_SOURCE_DIR}/${name}.json.in")
+ endif()
+ if(EXISTS "${CMakePresetsPackage_FILE}")
+ configure_file("${CMakePresetsPackage_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakePresets.json" @ONLY)
+ endif()
+
+ if(NOT CMakeUserPresets_FILE)
+ set(CMakeUserPresets_FILE "${RunCMake_SOURCE_DIR}/${name}User.json.in")
+ endif()
+ if(EXISTS "${CMakeUserPresets_FILE}")
+ configure_file("${CMakeUserPresets_FILE}" "${RunCMake_TEST_SOURCE_DIR}/CMakeUserPresets.json" @ONLY)
+ endif()
+
+ foreach(ASSET ${CMakePresetsPackage_ASSETS})
+ configure_file("${RunCMake_SOURCE_DIR}/${ASSET}" "${RunCMake_TEST_SOURCE_DIR}" COPYONLY)
+ endforeach()
+
+ if (NOT CMakePresetsPackage_NO_CONFIGURE)
+ foreach(CONFIGURE_PRESET ${CMakePresetsPackage_CONFIGURE_PRESETS})
+ run_cmake_command("${name}-configure-${CONFIGURE_PRESET}"
+ "${CMAKE_COMMAND}" "--preset" "${CONFIGURE_PRESET}")
+ endforeach()
+ endif()
+
+ if (NOT CMakePresetsPackage_NO_BUILD)
+ foreach(BUILD_PRESET ${CMakePresetsPackage_BUILD_PRESETS})
+ run_cmake_command("${name}-build-${BUILD_PRESET}"
+ "${CMAKE_COMMAND}" "--build" "--preset" "${BUILD_PRESET}")
+ endforeach()
+ endif()
+
+ set(eq 0)
+ foreach(PACKAGE_PRESET ${CMakePresetsPackage_PACKAGE_PRESETS})
+ file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}/default/_CPack_Packages")
+
+ if (EXISTS "${RunCMake_SOURCE_DIR}/${name}-package-${PACKAGE_PRESET}-check.cmake")
+ set(RunCMake-check-file "${name}-package-${PACKAGE_PRESET}-check.cmake")
+ else()
+ set(RunCMake-check-file "check.cmake")
+ endif()
+
+ if(eq)
+ run_cmake_command(${name}-package-${PACKAGE_PRESET}
+ ${CMAKE_CPACK_COMMAND} "--preset=${PACKAGE_PRESET}" ${ARGN})
+ set(eq 0)
+ else()
+ run_cmake_command(${name}-package-${PACKAGE_PRESET}
+ ${CMAKE_CPACK_COMMAND} "--preset" "${PACKAGE_PRESET}" ${ARGN})
+ set(eq 1)
+ endif()
+ endforeach()
+endfunction()
+
+function(check_cpack_packages generators contents)
+ include("${RunCMake_TEST_BINARY_DIR}/default/CPackConfig.cmake")
+
+ set(cpack_dir "${RunCMake_TEST_BINARY_DIR}/default/_CPack_Packages/${CPACK_TOPLEVEL_TAG}")
+ file(GLOB dirs RELATIVE "${cpack_dir}" "${cpack_dir}/*")
+ if(NOT dirs STREQUAL generators)
+ string(APPEND RunCMake_TEST_FAILED "Expected CPack generators: ${generators}\nActual CPack generators: ${dirs}\n")
+ endif()
+
+ if(contents)
+ foreach(dir IN LISTS dirs)
+ set(env_file "${cpack_dir}/${dir}/${CPACK_PACKAGE_FILE_NAME}/env.txt")
+ file(READ "${env_file}" actual_contents)
+ if(NOT contents STREQUAL actual_contents)
+ string(REPLACE "\n" "\n " contents_formatted "${contents}")
+ string(REPLACE "\n" "\n " actual_contents_formatted "${actual_contents}")
+ string(APPEND RunCMake_TEST_FAILED "Expected contents of ${env_file}:\n ${contents_formatted}\nActual contents:\n ${actual_contents_formatted}\n")
+ endif()
+ endforeach()
+ endif()
+
+ set(RunCMake_TEST_FAILED ${RunCMake_TEST_FAILED} PARENT_SCOPE)
+endfunction()
+
+run_cmake_package_presets(UnsupportedVersion "x" "" "")
+run_cmake_package_presets(Good "default" "build-default-debug" "no-environment;with-environment;generators;configurations;variables;config-file;debug;verbose;package-name;package-version;package-directory;vendor-name")
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-write-only-result.txt b/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file-CHMOD/CHMOD-write-only-result.txt
+++ b/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-result.txt
diff --git a/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt b/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt
new file mode 100644
index 0000000..325af70
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion-configure-x-stderr.txt
@@ -0,0 +1,2 @@
+^CMake Error: Could not read presets from [^
+]*/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion: File version must be 5 or higher for package preset support$
diff --git a/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion.json.in b/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion.json.in
new file mode 100644
index 0000000..e5f7240
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/UnsupportedVersion.json.in
@@ -0,0 +1,4 @@
+{
+ "version": 5,
+ "packagePresets": []
+}
diff --git a/Tests/RunCMake/CMakePresetsPackage/check.cmake b/Tests/RunCMake/CMakePresetsPackage/check.cmake
new file mode 100644
index 0000000..e79c4f1
--- /dev/null
+++ b/Tests/RunCMake/CMakePresetsPackage/check.cmake
@@ -0,0 +1,3 @@
+set(CMakePresets_VALIDATE_SCRIPT_PATH "${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.py")
+include("${RunCMake_SOURCE_DIR}/../CMakePresets/validate_schema.cmake")
+include("${RunCMake_SOURCE_DIR}/../CMakePresets/check.cmake")
diff --git a/Tests/RunCMake/CPack/DEB/Helpers.cmake b/Tests/RunCMake/CPack/DEB/Helpers.cmake
index 9b98ed4..8904c69 100644
--- a/Tests/RunCMake/CPack/DEB/Helpers.cmake
+++ b/Tests/RunCMake/CPack/DEB/Helpers.cmake
@@ -97,7 +97,7 @@ function(getMissingShlibsErrorExtra FILE RESULT_VAR)
string(APPEND error_extra "; errors \"${deb_install_files_errors}\"")
endif()
- if(READELF_EXECUTABLE)
+ if(CPACK_READELF_EXECUTABLE)
string(APPEND error_extra "; readelf \"\n")
# Only dynamically linked ELF files are included
@@ -106,7 +106,7 @@ function(getMissingShlibsErrorExtra FILE RESULT_VAR)
if(_FILE MATCHES "ELF.*shared object")
string(REGEX MATCH "(^.*):" _FILE_NAME "${_FILE}")
- execute_process(COMMAND ${READELF_EXECUTABLE} -d "${CMAKE_MATCH_1}"
+ execute_process(COMMAND ${CPACK_READELF_EXECUTABLE} -d "${CMAKE_MATCH_1}"
WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}"
RESULT_VARIABLE result
OUTPUT_VARIABLE output
diff --git a/Tests/RunCMake/CPack/DEB/Prerequirements.cmake b/Tests/RunCMake/CPack/DEB/Prerequirements.cmake
index 60d02e7..3b02579 100644
--- a/Tests/RunCMake/CPack/DEB/Prerequirements.cmake
+++ b/Tests/RunCMake/CPack/DEB/Prerequirements.cmake
@@ -14,9 +14,9 @@ function(get_test_prerequirements found_var config_file)
endif()
# optional tool for some tests
- find_program(READELF_EXECUTABLE NAMES readelf)
- if(READELF_EXECUTABLE)
+ find_program(CPACK_READELF_EXECUTABLE NAMES readelf)
+ if(CPACK_READELF_EXECUTABLE)
file(APPEND "${config_file}"
- "\nset(READELF_EXECUTABLE \"${READELF_EXECUTABLE}\")")
+ "\nset(CPACK_READELF_EXECUTABLE \"${CPACK_READELF_EXECUTABLE}\")")
endif()
endfunction()
diff --git a/Tests/RunCMake/CPack/RPM/Prerequirements.cmake b/Tests/RunCMake/CPack/RPM/Prerequirements.cmake
index e95cd15..a4741ba 100644
--- a/Tests/RunCMake/CPack/RPM/Prerequirements.cmake
+++ b/Tests/RunCMake/CPack/RPM/Prerequirements.cmake
@@ -15,9 +15,9 @@ function(get_test_prerequirements found_var config_file)
endif()
# optional tool for some tests
- find_program(OBJDUMP_EXECUTABLE objdump)
- if(OBJDUMP_EXECUTABLE)
+ find_program(CPACK_OBJDUMP_EXECUTABLE objdump)
+ if(CPACK_OBJDUMP_EXECUTABLE)
file(APPEND "${config_file}"
- "\nset(OBJDUMP_EXECUTABLE \"${OBJDUMP_EXECUTABLE}\")")
+ "\nset(CPACK_OBJDUMP_EXECUTABLE \"${CPACK_OBJDUMP_EXECUTABLE}\")")
endif()
endfunction()
diff --git a/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS/DEB-Prerequirements.cmake b/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS/DEB-Prerequirements.cmake
index be44b2e..b0bfc9d 100644
--- a/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS/DEB-Prerequirements.cmake
+++ b/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS/DEB-Prerequirements.cmake
@@ -1,7 +1,7 @@
function(get_test_prerequirements found_var config_file)
include(${config_file})
- if(READELF_EXECUTABLE)
+ if(CPACK_READELF_EXECUTABLE)
set(${found_var} true PARENT_SCOPE)
endif()
endfunction()
diff --git a/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/DEB-Prerequirements.cmake b/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/DEB-Prerequirements.cmake
index be44b2e..b0bfc9d 100644
--- a/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/DEB-Prerequirements.cmake
+++ b/Tests/RunCMake/CPack/tests/GENERATE_SHLIBS_LDCONFIG/DEB-Prerequirements.cmake
@@ -1,7 +1,7 @@
function(get_test_prerequirements found_var config_file)
include(${config_file})
- if(READELF_EXECUTABLE)
+ if(CPACK_READELF_EXECUTABLE)
set(${found_var} true PARENT_SCOPE)
endif()
endfunction()
diff --git a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-Prerequirements.cmake b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-Prerequirements.cmake
index 90cfe44..f5df8a2 100644
--- a/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-Prerequirements.cmake
+++ b/Tests/RunCMake/CPack/tests/INSTALL_SCRIPTS/RPM-Prerequirements.cmake
@@ -2,7 +2,7 @@ function(get_test_prerequirements found_var config_file)
if(SUBTEST_SUFFIX MATCHES ".*single_debug_info")
include(${config_file})
- if(OBJDUMP_EXECUTABLE)
+ if(CPACK_OBJDUMP_EXECUTABLE)
set(${found_var} true PARENT_SCOPE)
endif()
else()
diff --git a/Tests/RunCMake/CTestTimeout/TestTimeout.c b/Tests/RunCMake/CTestTimeout/TestTimeout.c
index 5a008a7..0d534fc 100644
--- a/Tests/RunCMake/CTestTimeout/TestTimeout.c
+++ b/Tests/RunCMake/CTestTimeout/TestTimeout.c
@@ -1,6 +1,7 @@
#if defined(_WIN32)
# include <windows.h>
#else
+# include <sched.h>
# include <unistd.h>
#endif
diff --git a/Tests/RunCMake/CXXModules/CMakeLists.txt b/Tests/RunCMake/CXXModules/CMakeLists.txt
new file mode 100644
index 0000000..708d92c
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/CMakeLists.txt
@@ -0,0 +1,6 @@
+cmake_minimum_required(VERSION 3.23)
+project(${RunCMake_TEST} NONE)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
+
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/CXXModules/ExportBuildCxxModules-check.cmake b/Tests/RunCMake/CXXModules/ExportBuildCxxModules-check.cmake
new file mode 100644
index 0000000..cb6f6bd
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/ExportBuildCxxModules-check.cmake
@@ -0,0 +1,40 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/export-modules-targets.cmake" export_script)
+
+if (NOT export_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules/cxx-modules\.cmake"\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find C++ module property script inclusion")
+endif ()
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules.cmake" trampoline_script)
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ if (NOT trampoline_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-[^.]*\.cmake" OPTIONAL\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find C++ module property per-config script inclusion(s)")
+ endif ()
+else ()
+ if (NOT trampoline_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-[^.]*\.cmake"\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find C++ module property per-config script inclusion(s)")
+ endif ()
+endif ()
+
+set(any_exists 0)
+foreach (config IN ITEMS noconfig Debug Release RelWithDebInfo MinSizeRel)
+ if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-${config}.cmake")
+ continue ()
+ endif ()
+ set(any_exists 1)
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/lib/cmake/export-modules/cxx-modules/cxx-modules-${config}.cmake" config_script)
+
+ if (NOT config_script MATCHES "include\\(\"\\\${CMAKE_CURRENT_LIST_DIR}/target-export-name-${config}\\.cmake\"\\)")
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find C++ module per-target property script inclusion")
+ endif ()
+endforeach ()
+
+if (NOT any_exists)
+ list(APPEND RunCMake_TEST_FAILED
+ "No per-configuration target files exist.")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/ExportBuildCxxModules-stderr.txt b/Tests/RunCMake/CXXModules/ExportBuildCxxModules-stderr.txt
new file mode 100644
index 0000000..c05b0b4
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/ExportBuildCxxModules-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at ExportBuildCxxModules.cmake:6 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/ExportBuildCxxModules.cmake b/Tests/RunCMake/CXXModules/ExportBuildCxxModules.cmake
new file mode 100644
index 0000000..850f8dc
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/ExportBuildCxxModules.cmake
@@ -0,0 +1,22 @@
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+add_library(export-modules)
+target_sources(export-modules
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(export-modules
+ PRIVATE
+ cxx_std_20)
+set_property(TARGET export-modules
+ PROPERTY EXPORT_NAME export-name)
+
+install(TARGETS export-modules
+ EXPORT exp
+ FILE_SET fs DESTINATION "include/cxx/export-modules")
+
+export(EXPORT exp
+ FILE "${CMAKE_BINARY_DIR}/lib/cmake/export-modules/export-modules-targets.cmake"
+ CXX_MODULES_DIRECTORY "cxx-modules")
diff --git a/Tests/RunCMake/CXXModules/ExportInstallCxxModules-check.cmake b/Tests/RunCMake/CXXModules/ExportInstallCxxModules-check.cmake
new file mode 100644
index 0000000..9e83fd8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/ExportInstallCxxModules-check.cmake
@@ -0,0 +1,35 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/exp.cmake" export_script)
+
+if (NOT export_script MATCHES [[include\("\${CMAKE_CURRENT_LIST_DIR}/cxx-modules/cxx-modules\.cmake"\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find C++ module property script inclusion")
+endif ()
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules.cmake" trampoline_script)
+
+if (NOT trampoline_script MATCHES [[file\(GLOB _cmake_cxx_module_includes "\${CMAKE_CURRENT_LIST_DIR}/cxx-modules-\*\.cmake"\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find C++ module property per-config script inclusion(s)")
+endif ()
+
+set(any_exists 0)
+foreach (config IN ITEMS noconfig Debug Release RelWithDebInfo MinSizeRel)
+ if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules-${config}.cmake")
+ continue ()
+ endif ()
+ set(any_exists 1)
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/Export/eee57a7e91412f1be699e9b63fa9d601/cxx-modules/cxx-modules-${config}.cmake" config_script)
+
+ if (NOT config_script MATCHES "include\\(\"\\\${CMAKE_CURRENT_LIST_DIR}/target-export-name-${config}\\.cmake\"\\)")
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find C++ module per-target property script inclusion")
+ endif ()
+endforeach ()
+
+if (NOT any_exists)
+ list(APPEND RunCMake_TEST_FAILED
+ "No per-configuration target files exist.")
+endif ()
+
+string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/ExportInstallCxxModules-stderr.txt b/Tests/RunCMake/CXXModules/ExportInstallCxxModules-stderr.txt
new file mode 100644
index 0000000..4fe27a9
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/ExportInstallCxxModules-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at ExportInstallCxxModules.cmake:6 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/ExportInstallCxxModules.cmake b/Tests/RunCMake/CXXModules/ExportInstallCxxModules.cmake
new file mode 100644
index 0000000..234a4b5
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/ExportInstallCxxModules.cmake
@@ -0,0 +1,22 @@
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+add_library(export-modules)
+target_sources(export-modules
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(export-modules
+ PRIVATE
+ cxx_std_20)
+set_property(TARGET export-modules
+ PROPERTY EXPORT_NAME export-name)
+
+install(TARGETS export-modules
+ EXPORT exp
+ FILE_SET fs DESTINATION "include/cxx/export-modules")
+
+install(EXPORT exp
+ DESTINATION "lib/cmake/export-modules"
+ CXX_MODULES_DIRECTORY "cxx-modules")
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-result.txt b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-result.txt
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface-result.txt
diff --git a/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface-stderr.txt b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface-stderr.txt
new file mode 100644
index 0000000..d573a02
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at FileSetModuleHeaderUnitsInterface.cmake:2 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at FileSetModuleHeaderUnitsInterface.cmake:2 \(target_sources\):
+ target_sources File set TYPEs "CXX_MODULES" and "CXX_MODULE_HEADER_UNITS"
+ may not have "INTERFACE" visibility
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
diff --git a/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface.cmake b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface.cmake
new file mode 100644
index 0000000..03ca17e
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterface.cmake
@@ -0,0 +1,8 @@
+add_library(module-header)
+target_sources(module-header
+ INTERFACE
+ FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
+ sources/module-header.h)
+target_compile_features(module-header
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterfaceImported-stderr.txt b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterfaceImported-stderr.txt
new file mode 100644
index 0000000..1b4ba5d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterfaceImported-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at FileSetModuleHeaderUnitsInterfaceImported.cmake:2 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterfaceImported.cmake b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterfaceImported.cmake
new file mode 100644
index 0000000..9ff5606
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsInterfaceImported.cmake
@@ -0,0 +1,8 @@
+add_library(module-header SHARED IMPORTED)
+target_sources(module-header
+ INTERFACE
+ FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
+ sources/module-header.h)
+target_compile_features(module-header
+ INTERFACE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPrivate-stderr.txt b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPrivate-stderr.txt
new file mode 100644
index 0000000..a7ac88e
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPrivate-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at FileSetModuleHeaderUnitsPrivate.cmake:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPrivate.cmake b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPrivate.cmake
new file mode 100644
index 0000000..ebf9853
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPrivate.cmake
@@ -0,0 +1,13 @@
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+add_library(module-header
+ sources/cxx-anchor.cxx)
+target_sources(module-header
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
+ sources/module-header.h)
+target_compile_features(module-header
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPublic-stderr.txt b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPublic-stderr.txt
new file mode 100644
index 0000000..a5b4ede
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPublic-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at FileSetModuleHeaderUnitsPublic.cmake:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPublic.cmake b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPublic.cmake
new file mode 100644
index 0000000..3dfccbb5
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModuleHeaderUnitsPublic.cmake
@@ -0,0 +1,13 @@
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+add_library(module-header
+ sources/cxx-anchor.cxx)
+target_sources(module-header
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
+ sources/module-header.h)
+target_compile_features(module-header
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-result.txt b/Tests/RunCMake/CXXModules/FileSetModulesInterface-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-result.txt
+++ b/Tests/RunCMake/CXXModules/FileSetModulesInterface-result.txt
diff --git a/Tests/RunCMake/CXXModules/FileSetModulesInterface-stderr.txt b/Tests/RunCMake/CXXModules/FileSetModulesInterface-stderr.txt
new file mode 100644
index 0000000..81a35e8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModulesInterface-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at FileSetModulesInterface.cmake:2 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at FileSetModulesInterface.cmake:2 \(target_sources\):
+ target_sources File set TYPEs "CXX_MODULES" and "CXX_MODULE_HEADER_UNITS"
+ may not have "INTERFACE" visibility
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
diff --git a/Tests/RunCMake/CXXModules/FileSetModulesInterface.cmake b/Tests/RunCMake/CXXModules/FileSetModulesInterface.cmake
new file mode 100644
index 0000000..24cec3e
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModulesInterface.cmake
@@ -0,0 +1,8 @@
+add_library(module)
+target_sources(module
+ INTERFACE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(module
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/FileSetModulesInterfaceImported-stderr.txt b/Tests/RunCMake/CXXModules/FileSetModulesInterfaceImported-stderr.txt
new file mode 100644
index 0000000..4420bbc
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModulesInterfaceImported-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at FileSetModulesInterfaceImported.cmake:2 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/FileSetModulesInterfaceImported.cmake b/Tests/RunCMake/CXXModules/FileSetModulesInterfaceImported.cmake
new file mode 100644
index 0000000..6640ae9
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModulesInterfaceImported.cmake
@@ -0,0 +1,8 @@
+add_library(module SHARED IMPORTED)
+target_sources(module
+ INTERFACE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(module
+ INTERFACE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/FileSetModulesPrivate-stderr.txt b/Tests/RunCMake/CXXModules/FileSetModulesPrivate-stderr.txt
new file mode 100644
index 0000000..03e06cc
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModulesPrivate-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at FileSetModulesPrivate.cmake:6 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/FileSetModulesPrivate.cmake b/Tests/RunCMake/CXXModules/FileSetModulesPrivate.cmake
new file mode 100644
index 0000000..ca18982
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModulesPrivate.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+add_library(module)
+target_sources(module
+ PRIVATE
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(module
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/FileSetModulesPublic-stderr.txt b/Tests/RunCMake/CXXModules/FileSetModulesPublic-stderr.txt
new file mode 100644
index 0000000..0c110c3
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModulesPublic-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at FileSetModulesPublic.cmake:6 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/FileSetModulesPublic.cmake b/Tests/RunCMake/CXXModules/FileSetModulesPublic.cmake
new file mode 100644
index 0000000..58de174
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/FileSetModulesPublic.cmake
@@ -0,0 +1,12 @@
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+add_library(module)
+target_sources(module
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(module
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/InstallBMI-check.cmake b/Tests/RunCMake/CXXModules/InstallBMI-check.cmake
new file mode 100644
index 0000000..f891c80
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMI-check.cmake
@@ -0,0 +1,24 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script)
+
+if (NOT install_script MATCHES [[\(CMAKE_INSTALL_COMPONENT STREQUAL "bmi" OR NOT CMAKE_INSTALL_COMPONENT\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find BMI install script component for `bmi`")
+endif ()
+
+if (NOT install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find BMI install script inclusion")
+endif ()
+
+if (NOT install_script MATCHES [[\(CMAKE_INSTALL_COMPONENT STREQUAL "bmi-optional"\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find BMI install script component for `bmi-optional`")
+endif ()
+
+if (NOT install_script MATCHES [[\(CMAKE_INSTALL_COMPONENT STREQUAL "bmi-only-debug" OR NOT CMAKE_INSTALL_COMPONENT\)
+ if\(CMAKE_INSTALL_CONFIG_NAME MATCHES "\^\(\[Dd\]\[Ee\]\[Bb\]\[Uu\]\[Gg\]\)\$"\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find BMI install script component for `bmi-only-debug`")
+endif ()
+
+string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/InstallBMI-stderr.txt b/Tests/RunCMake/CXXModules/InstallBMI-stderr.txt
new file mode 100644
index 0000000..fc3c7db
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMI-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at InstallBMI.cmake:8 \(install\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/InstallBMI.cmake b/Tests/RunCMake/CXXModules/InstallBMI.cmake
new file mode 100644
index 0000000..f0947b4
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMI.cmake
@@ -0,0 +1,23 @@
+enable_language(CXX)
+
+add_library(install-bmi)
+target_sources(install-bmi
+ PRIVATE
+ sources/cxx-anchor.cxx)
+
+install(TARGETS install-bmi
+ CXX_MODULES_BMI
+ DESTINATION "lib/bmi"
+ COMPONENT "bmi")
+
+install(TARGETS install-bmi
+ CXX_MODULES_BMI
+ DESTINATION "lib/bmi"
+ EXCLUDE_FROM_ALL
+ COMPONENT "bmi-optional")
+
+install(TARGETS install-bmi
+ CXX_MODULES_BMI
+ DESTINATION "lib/bmi"
+ CONFIGURATIONS Debug
+ COMPONENT "bmi-only-debug")
diff --git a/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-check.cmake b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-check.cmake
new file mode 100644
index 0000000..32a37ad
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-check.cmake
@@ -0,0 +1,8 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script)
+
+if (NOT install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi-generic-args\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Could not find BMI install script inclusion")
+endif ()
+
+string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-stderr.txt b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-stderr.txt
new file mode 100644
index 0000000..44c961f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at InstallBMIGenericArgs.cmake:8 \(install\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/InstallBMIGenericArgs.cmake b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs.cmake
new file mode 100644
index 0000000..8f17143
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMIGenericArgs.cmake
@@ -0,0 +1,9 @@
+enable_language(CXX)
+
+add_library(install-bmi-generic-args)
+target_sources(install-bmi-generic-args
+ PRIVATE
+ sources/cxx-anchor.cxx)
+
+install(TARGETS install-bmi-generic-args
+ DESTINATION "bin")
diff --git a/Tests/RunCMake/CXXModules/InstallBMIIgnore-check.cmake b/Tests/RunCMake/CXXModules/InstallBMIIgnore-check.cmake
new file mode 100644
index 0000000..7d13ef0
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMIIgnore-check.cmake
@@ -0,0 +1,13 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script)
+
+if (install_script MATCHES [[\(CMAKE_INSTALL_COMPONENT STREQUAL "bmi" OR NOT CMAKE_INSTALL_COMPONENT\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Found BMI install script component for `bmi`")
+endif ()
+
+if (install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi-ignore\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Found BMI install script inclusion")
+endif ()
+
+string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/InstallBMIIgnore-stderr.txt b/Tests/RunCMake/CXXModules/InstallBMIIgnore-stderr.txt
new file mode 100644
index 0000000..d9d2c2d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMIIgnore-stderr.txt
@@ -0,0 +1,6 @@
+CMake Warning \(dev\) at InstallBMIIgnore.cmake:5 \(install\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake b/Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake
new file mode 100644
index 0000000..f339511
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMIIgnore.cmake
@@ -0,0 +1,9 @@
+enable_language(CXX)
+
+add_library(install-bmi-ignore INTERFACE)
+
+install(TARGETS install-bmi-ignore
+ CXX_MODULES_BMI
+ # An empty destination ignores BMI installation.
+ DESTINATION ""
+ COMPONENT "bmi")
diff --git a/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake b/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake
new file mode 100644
index 0000000..412e260
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/InstallBMINoGenericArgs-check.cmake
@@ -0,0 +1,8 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/cmake_install.cmake" install_script)
+
+if (install_script MATCHES [[include\("[^)]*/CMakeFiles/install-bmi-generic-args\.dir/install-cxx-module-bmi-[^.]*\.cmake" OPTIONAL\)]])
+ list(APPEND RunCMake_TEST_FAILED
+ "Found BMI install script inclusion")
+endif ()
+
+string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall-check.cmake b/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall-check.cmake
new file mode 100644
index 0000000..0d08c44
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall-check.cmake
@@ -0,0 +1,34 @@
+include("${CMAKE_CURRENT_LIST_DIR}/check-json.cmake")
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(have_file 0)
+ foreach (config IN ITEMS Release Debug RelWithDebInfo MinSizeRel)
+ if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-bmi-install-public.dir/${config}/CXXDependInfo.json")
+ continue ()
+ endif ()
+ set(have_file 1)
+
+ set(CMAKE_BUILD_TYPE "${config}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-bmi-install-public.dir/${config}/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoBMIInstall-public.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-bmi-install-private.dir/${config}/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoBMIInstall-private.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+ endforeach ()
+
+ if (NOT have_file)
+ list(APPEND RunCMake_TEST_FAILED
+ "No recognized build configurations found.")
+ endif ()
+else ()
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-bmi-install-public.dir/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoBMIInstall-public.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-bmi-install-private.dir/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoBMIInstall-private.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall-stderr.txt b/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall-stderr.txt
new file mode 100644
index 0000000..ebf7be5
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at NinjaDependInfoBMIInstall.cmake:14 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall.cmake b/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall.cmake
new file mode 100644
index 0000000..32dc42d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoBMIInstall.cmake
@@ -0,0 +1,76 @@
+# Fake out that we have dyndep; we only need to generate, not actually build
+# here.
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+enable_language(CXX)
+
+if (NOT CMAKE_GENERATOR MATCHES "Ninja")
+ message(FATAL_ERROR
+ "This test requires a 'Ninja' generator to be used.")
+endif ()
+
+add_library(ninja-bmi-install-public)
+target_sources(ninja-bmi-install-public
+ PRIVATE
+ sources/module-impl.cxx
+ sources/module-internal-part-impl.cxx
+ sources/module-part-impl.cxx
+ sources/module-use.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/sources"
+ FILES
+ sources/module.cxx
+ sources/module-part.cxx
+ FILE_SET internal_partitions TYPE CXX_MODULES FILES
+ sources/module-internal-part.cxx)
+target_compile_features(ninja-bmi-install-public
+ PRIVATE
+ cxx_std_20)
+set_property(TARGET ninja-bmi-install-public
+ PROPERTY EXPORT_NAME "with-public")
+
+install(TARGETS ninja-bmi-install-public
+ FILE_SET modules
+ DESTINATION "lib/cxx"
+ COMPONENT "modules"
+ FILE_SET internal_partitions
+ DESTINATION "lib/cxx/internals"
+ COMPONENT "modules-internal"
+ CXX_MODULES_BMI
+ DESTINATION "lib/cxx/modules/$<CONFIG>"
+ COMPONENT "bmi")
+
+add_library(ninja-bmi-install-private)
+target_sources(ninja-bmi-install-private
+ PRIVATE
+ sources/module-impl.cxx
+ sources/module-internal-part-impl.cxx
+ sources/module-part-impl.cxx
+ sources/module-use.cxx
+ PRIVATE
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/sources"
+ FILES
+ sources/module.cxx
+ sources/module-part.cxx
+ FILE_SET internal_partitions TYPE CXX_MODULES FILES
+ sources/module-internal-part.cxx)
+target_compile_features(ninja-bmi-install-private
+ PRIVATE
+ cxx_std_20)
+set_property(TARGET ninja-bmi-install-private
+ PROPERTY EXPORT_NAME "with-private")
+
+set(CMAKE_INSTALL_MESSAGE LAZY)
+install(TARGETS ninja-bmi-install-private
+ CXX_MODULES_BMI
+ DESTINATION "lib/cxx/modules/private/$<CONFIG>"
+ PERMISSIONS
+ OWNER_READ OWNER_WRITE
+ GROUP_READ
+ WORLD_READ
+ COMPONENT "bmi")
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoExport-check.cmake b/Tests/RunCMake/CXXModules/NinjaDependInfoExport-check.cmake
new file mode 100644
index 0000000..7720257
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoExport-check.cmake
@@ -0,0 +1,34 @@
+include("${CMAKE_CURRENT_LIST_DIR}/check-json.cmake")
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(have_file 0)
+ foreach (config IN ITEMS Release Debug RelWithDebInfo MinSizeRel)
+ if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-public.dir/${config}/CXXDependInfo.json")
+ continue ()
+ endif ()
+ set(have_file 1)
+
+ set(CMAKE_BUILD_TYPE "${config}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-public.dir/${config}/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoExport-public.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-private.dir/${config}/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoExport-private.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+ endforeach ()
+
+ if (NOT have_file)
+ list(APPEND RunCMake_TEST_FAILED
+ "No recognized build configurations found.")
+ endif ()
+else ()
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-public.dir/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoExport-public.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-exports-private.dir/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoExport-private.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoExport-stderr.txt b/Tests/RunCMake/CXXModules/NinjaDependInfoExport-stderr.txt
new file mode 100644
index 0000000..e328223
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoExport-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at NinjaDependInfoExport.cmake:14 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoExport.cmake b/Tests/RunCMake/CXXModules/NinjaDependInfoExport.cmake
new file mode 100644
index 0000000..05e7ef7
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoExport.cmake
@@ -0,0 +1,85 @@
+# Fake out that we have dyndep; we only need to generate, not actually build
+# here.
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+enable_language(CXX)
+
+if (NOT CMAKE_GENERATOR MATCHES "Ninja")
+ message(FATAL_ERROR
+ "This test requires a 'Ninja' generator to be used.")
+endif ()
+
+add_library(ninja-exports-public)
+target_sources(ninja-exports-public
+ PRIVATE
+ sources/module-impl.cxx
+ sources/module-internal-part-impl.cxx
+ sources/module-part-impl.cxx
+ sources/module-use.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/sources"
+ FILES
+ sources/module.cxx
+ sources/module-part.cxx
+ FILE_SET internal_partitions TYPE CXX_MODULES FILES
+ sources/module-internal-part.cxx)
+target_compile_features(ninja-exports-public
+ PRIVATE
+ cxx_std_20)
+set_property(TARGET ninja-exports-public
+ PROPERTY EXPORT_NAME "with-public")
+
+install(TARGETS ninja-exports-public
+ EXPORT exp
+ FILE_SET modules
+ DESTINATION "lib/cxx"
+ COMPONENT "modules"
+ FILE_SET internal_partitions
+ DESTINATION "lib/cxx/internals"
+ COMPONENT "modules-internal")
+
+add_library(ninja-exports-private)
+target_sources(ninja-exports-private
+ PRIVATE
+ sources/module-impl.cxx
+ sources/module-internal-part-impl.cxx
+ sources/module-part-impl.cxx
+ sources/module-use.cxx
+ PRIVATE
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/sources"
+ FILES
+ sources/module.cxx
+ sources/module-part.cxx
+ FILE_SET internal_partitions TYPE CXX_MODULES FILES
+ sources/module-internal-part.cxx)
+target_compile_features(ninja-exports-private
+ PRIVATE
+ cxx_std_20)
+set_property(TARGET ninja-exports-private
+ PROPERTY EXPORT_NAME "with-private")
+
+install(TARGETS ninja-exports-private
+ EXPORT exp)
+
+# Test multiple build exports.
+export(EXPORT exp
+ FILE "${CMAKE_BINARY_DIR}/lib/cmake/export1/export1-targets.cmake"
+ NAMESPACE export1::
+ CXX_MODULES_DIRECTORY "cxx-modules")
+export(EXPORT exp
+ FILE "${CMAKE_BINARY_DIR}/lib/cmake/export2/export2-targets.cmake"
+ CXX_MODULES_DIRECTORY "cxx-modules")
+
+# Test multiple install exports.
+install(EXPORT exp
+ DESTINATION "lib/cmake/export1"
+ NAMESPACE export1::
+ CXX_MODULES_DIRECTORY "cxx-modules")
+install(EXPORT exp
+ DESTINATION "lib/cmake/export2"
+ CXX_MODULES_DIRECTORY "cxx-modules")
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-check.cmake b/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-check.cmake
new file mode 100644
index 0000000..b9a1315
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-check.cmake
@@ -0,0 +1,34 @@
+include("${CMAKE_CURRENT_LIST_DIR}/check-json.cmake")
+
+if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(have_file 0)
+ foreach (config IN ITEMS Release Debug RelWithDebInfo MinSizeRel)
+ if (NOT EXISTS "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-file-sets-public.dir/${config}/CXXDependInfo.json")
+ continue ()
+ endif ()
+ set(have_file 1)
+
+ set(CMAKE_BUILD_TYPE "${config}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-file-sets-public.dir/${config}/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoFileSet-public.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-file-sets-private.dir/${config}/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoFileSet-private.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+ endforeach ()
+
+ if (NOT have_file)
+ list(APPEND RunCMake_TEST_FAILED
+ "No recognized build configurations found.")
+ endif ()
+else ()
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-file-sets-public.dir/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoFileSet-public.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+
+ file(READ "${RunCMake_TEST_BINARY_DIR}/CMakeFiles/ninja-file-sets-private.dir/CXXDependInfo.json" actual_contents)
+ file(READ "${CMAKE_CURRENT_LIST_DIR}/expect/NinjaDependInfoFileSet-private.json" expect_contents)
+ check_json("${actual_contents}" "${expect_contents}")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-stderr.txt b/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-stderr.txt
new file mode 100644
index 0000000..ca430cc
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet-stderr.txt
@@ -0,0 +1,11 @@
+CMake Warning \(dev\) at NinjaDependInfoFileSet.cmake:14 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet.cmake b/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet.cmake
new file mode 100644
index 0000000..74e729e
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NinjaDependInfoFileSet.cmake
@@ -0,0 +1,59 @@
+# Fake out that we have dyndep; we only need to generate, not actually build
+# here.
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+enable_language(CXX)
+
+if (NOT CMAKE_GENERATOR MATCHES "Ninja")
+ message(FATAL_ERROR
+ "This test requires a 'Ninja' generator to be used.")
+endif ()
+
+add_library(ninja-file-sets-public)
+target_sources(ninja-file-sets-public
+ PRIVATE
+ sources/module-impl.cxx
+ sources/module-internal-part-impl.cxx
+ sources/module-part-impl.cxx
+ sources/module-use.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/sources"
+ FILES
+ sources/module.cxx
+ sources/module-part.cxx
+ FILE_SET internal_partitions TYPE CXX_MODULES FILES
+ sources/module-internal-part.cxx)
+target_compile_features(ninja-file-sets-public
+ PRIVATE
+ cxx_std_20)
+
+install(TARGETS ninja-file-sets-public
+ FILE_SET modules
+ DESTINATION "lib/cxx"
+ COMPONENT "modules"
+ FILE_SET internal_partitions
+ DESTINATION "lib/cxx/internals"
+ COMPONENT "modules-internal")
+
+add_library(ninja-file-sets-private)
+target_sources(ninja-file-sets-private
+ PRIVATE
+ sources/module-impl.cxx
+ sources/module-internal-part-impl.cxx
+ sources/module-part-impl.cxx
+ sources/module-use.cxx
+ PRIVATE
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}/sources"
+ FILES
+ sources/module.cxx
+ sources/module-part.cxx
+ FILE_SET internal_partitions TYPE CXX_MODULES FILES
+ sources/module-internal-part.cxx)
+target_compile_features(ninja-file-sets-private
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-result.txt b/Tests/RunCMake/CXXModules/NoCXX-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-result.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX-result.txt
diff --git a/Tests/RunCMake/CXXModules/NoCXX-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX-stderr.txt
new file mode 100644
index 0000000..aa7f406
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX-stderr.txt
@@ -0,0 +1,20 @@
+CMake Warning \(dev\) at NoCXX.cmake:4 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error in CMakeLists.txt:
+ The "nocxx" target has C\+\+ module sources but the "CXX" language has not
+ been enabled
+
+(
+CMake Error in CMakeLists.txt:
+( The "nocxx" target has C\+\+ module sources but the "CXX" language has not
+ been enabled
+| The "nocxx" target contains C\+\+ module sources which are not supported by
+ the generator
+)
+)*
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoCXX.cmake b/Tests/RunCMake/CXXModules/NoCXX.cmake
new file mode 100644
index 0000000..3c46f9d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX.cmake
@@ -0,0 +1,9 @@
+enable_language(C)
+
+add_library(nocxx)
+target_sources(nocxx
+ PRIVATE
+ sources/c-anchor.c
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-result.txt b/Tests/RunCMake/CXXModules/NoCXX20-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-result.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX20-result.txt
diff --git a/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt
new file mode 100644
index 0000000..95d73b1
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX20-stderr.txt
@@ -0,0 +1,20 @@
+CMake Warning \(dev\) at NoCXX20.cmake:4 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error in CMakeLists.txt:
+ The "nocxx20" target has C\+\+ module sources but is not using at least
+ "cxx_std_20"
+
+(
+CMake Error in CMakeLists.txt:
+( The "nocxx20" target has C\+\+ module sources but is not using at least
+ "cxx_std_20"
+| The "nocxx20" target contains C\+\+ module sources which are not supported by
+ the generator
+)
+)*
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoCXX20.cmake b/Tests/RunCMake/CXXModules/NoCXX20.cmake
new file mode 100644
index 0000000..b7372e8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX20.cmake
@@ -0,0 +1,11 @@
+enable_language(CXX)
+
+add_library(nocxx20)
+target_sources(nocxx20
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+set_target_properties(nocxx20
+ PROPERTIES
+ CXX_STANDARD 17
+ CXX_STANDARD_REQUIRED ON)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-result.txt b/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-result.txt
index d00491f..d00491f 100644
--- a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-result.txt
+++ b/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-result.txt
diff --git a/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt b/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt
new file mode 100644
index 0000000..5f90ec8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag-stderr.txt
@@ -0,0 +1,20 @@
+CMake Warning \(dev\) at NoCXX20ModuleFlag.cmake:4 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error in CMakeLists.txt:
+ The "noexperimentalflag" target has C\+\+ module sources but its experimental
+ support has not been requested
+
+(
+CMake Error in CMakeLists.txt:
+( The "noexperimentalflag" target has C\+\+ module sources but its experimental
+ support has not been requested
+| The "noexperimentalflag" target contains C\+\+ module sources which are not
+ supported by the generator
+)
+)*
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag.cmake b/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag.cmake
new file mode 100644
index 0000000..5f896f9
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoCXX20ModuleFlag.cmake
@@ -0,0 +1,10 @@
+enable_language(CXX)
+
+add_library(noexperimentalflag)
+target_sources(noexperimentalflag
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(noexperimentalflag
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/NoDyndepSupport-result.txt b/Tests/RunCMake/CXXModules/NoDyndepSupport-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoDyndepSupport-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt b/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt
new file mode 100644
index 0000000..52f781f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoDyndepSupport-stderr.txt
@@ -0,0 +1,30 @@
+CMake Warning \(dev\) at NoDyndepSupport.cmake:10 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+(CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error:
+ The Ninja generator does not support C\+\+20 modules using Ninja version
+
+ .*
+
+ due to lack of required features. Ninja 1.10 or higher is required.
+
+|CMake Error in CMakeLists.txt:
+ The "nodyndep" target contains C\+\+ module sources which are not supported
+ by the generator
+
+(
+CMake Error in CMakeLists.txt:
+ The "nodyndep" target contains C\+\+ module sources which are not supported
+ by the generator
+
+)*)
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NoDyndepSupport.cmake b/Tests/RunCMake/CXXModules/NoDyndepSupport.cmake
new file mode 100644
index 0000000..0954400
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NoDyndepSupport.cmake
@@ -0,0 +1,16 @@
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+if (NOT CMAKE_CXX_STANDARD_DEFAULT)
+ set(CMAKE_CXX_STANDARD_DEFAULT "11")
+endif ()
+
+add_library(nodyndep)
+target_sources(nodyndep
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/module.cxx)
+target_compile_features(nodyndep
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits-result.txt b/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits-stderr.txt b/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits-stderr.txt
new file mode 100644
index 0000000..a93eb40
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits-stderr.txt
@@ -0,0 +1,22 @@
+CMake Warning \(dev\) at NotCXXSourceModuleHeaderUnits.cmake:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error in CMakeLists.txt:
+ Target "not-cxx-source" contains the source
+
+ .*/Tests/RunCMake/CXXModules/sources/c-anchor.c
+
+ in a file set of type "CXX_MODULE_HEADER_UNITS" but the source is not
+ classified as a "CXX" source.
+
+
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits.cmake b/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits.cmake
new file mode 100644
index 0000000..af4ddac
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NotCXXSourceModuleHeaderUnits.cmake
@@ -0,0 +1,15 @@
+enable_language(C)
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+add_library(not-cxx-source)
+target_sources(not-cxx-source
+ PRIVATE
+ sources/cxx-anchor.cxx
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULE_HEADER_UNITS FILES
+ sources/c-anchor.c)
+target_compile_features(not-cxx-source
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/NotCXXSourceModules-result.txt b/Tests/RunCMake/CXXModules/NotCXXSourceModules-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NotCXXSourceModules-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/NotCXXSourceModules-stderr.txt b/Tests/RunCMake/CXXModules/NotCXXSourceModules-stderr.txt
new file mode 100644
index 0000000..d341c1f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NotCXXSourceModules-stderr.txt
@@ -0,0 +1,17 @@
+CMake Warning \(dev\) at NotCXXSourceModules.cmake:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:6 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error in CMakeLists.txt:
+ Target "not-cxx-source" contains the source
+
+ .*/Tests/RunCMake/CXXModules/sources/c-anchor.c
+
+ in a file set of type "CXX_MODULES" but the source is not classified as a
+ "CXX" source.
+
+
+CMake Generate step failed. Build files cannot be regenerated correctly.
diff --git a/Tests/RunCMake/CXXModules/NotCXXSourceModules.cmake b/Tests/RunCMake/CXXModules/NotCXXSourceModules.cmake
new file mode 100644
index 0000000..f7a6060
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/NotCXXSourceModules.cmake
@@ -0,0 +1,13 @@
+enable_language(C)
+enable_language(CXX)
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP 1)
+set(CMAKE_EXPERIMENTAL_CXX_SCANDEP_SOURCE "")
+
+add_library(not-cxx-source)
+target_sources(not-cxx-source
+ PUBLIC
+ FILE_SET fs TYPE CXX_MODULES FILES
+ sources/c-anchor.c)
+target_compile_features(not-cxx-source
+ PRIVATE
+ cxx_std_20)
diff --git a/Tests/RunCMake/CXXModules/RunCMakeTest.cmake b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
new file mode 100644
index 0000000..3f17c1f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/RunCMakeTest.cmake
@@ -0,0 +1,170 @@
+include(RunCMake)
+
+# For `if (IN_LIST)`
+cmake_policy(SET CMP0057 NEW)
+
+run_cmake(compiler_introspection)
+include("${RunCMake_BINARY_DIR}/compiler_introspection-build/info.cmake")
+
+# Test negative cases where C++20 modules do not work.
+run_cmake(NoCXX)
+if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+ # This test requires that the compiler be told to compile in an older-than-20
+ # standard. If the compiler forces a standard to be used, skip it.
+ if (NOT forced_cxx_standard)
+ run_cmake(NoCXX20)
+ endif ()
+
+ # This test uses C++20, but another prerequisite is missing, so forced
+ # standards don't matter.
+ run_cmake(NoCXX20ModuleFlag)
+endif ()
+
+if (RunCMake_GENERATOR MATCHES "Ninja")
+ execute_process(
+ COMMAND "${CMAKE_MAKE_PROGRAM}" --version
+ RESULT_VARIABLE res
+ OUTPUT_VARIABLE ninja_version
+ ERROR_VARIABLE err
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ ERROR_STRIP_TRAILING_WHITESPACE)
+
+ if (res)
+ message(WARNING
+ "Failed to determine `ninja` version: ${err}")
+ set(ninja_version "0")
+ endif ()
+endif ()
+
+# Test behavior when the generator does not support C++20 modules.
+if (NOT RunCMake_GENERATOR MATCHES "Ninja" OR
+ ninja_version VERSION_LESS "1.10" OR
+ NOT "cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+ if ("cxx_std_20" IN_LIST CMAKE_CXX_COMPILE_FEATURES)
+ run_cmake(NoDyndepSupport)
+ endif ()
+
+ # Bail; the remaining tests require the generator to successfully generate
+ # with C++20 modules in the source list.
+ return ()
+endif ()
+
+set(fileset_types
+ Modules
+ ModuleHeaderUnits)
+set(scopes
+ Interface
+ Private
+ Public)
+foreach (fileset_type IN LISTS fileset_types)
+ foreach (scope IN LISTS scopes)
+ run_cmake("FileSet${fileset_type}${scope}")
+ endforeach ()
+ run_cmake("FileSet${fileset_type}InterfaceImported")
+
+ # Test the error message when a non-C++ source file is found in the source
+ # list.
+ run_cmake("NotCXXSource${fileset_type}")
+endforeach ()
+
+run_cmake(InstallBMI)
+run_cmake(InstallBMIGenericArgs)
+run_cmake(InstallBMIIgnore)
+
+run_cmake(ExportBuildCxxModules)
+run_cmake(ExportInstallCxxModules)
+
+# Generator-specific tests.
+if (RunCMake_GENERATOR MATCHES "Ninja")
+ run_cmake(NinjaDependInfoFileSet)
+ run_cmake(NinjaDependInfoExport)
+ run_cmake(NinjaDependInfoBMIInstall)
+else ()
+ message(FATAL_ERROR
+ "Please add 'DependInfo' tests for the '${RunCMake_GENERATOR}' generator.")
+endif ()
+
+# Actual compilation tests.
+if (NOT CMake_TEST_MODULE_COMPILATION)
+ return ()
+endif ()
+
+function (run_cxx_module_test directory)
+ set(test_name "${directory}")
+ if (NOT ARGN STREQUAL "")
+ list(POP_FRONT ARGN test_name)
+ endif ()
+
+ set(RunCMake_TEST_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}/examples/${directory}")
+ set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/examples/${test_name}-build")
+
+ if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ set(RunCMake_TEST_OPTIONS -DCMAKE_CONFIGURATION_TYPES=Debug)
+ else ()
+ set(RunCMake_TEST_OPTIONS -DCMAKE_BUILD_TYPE=Debug)
+ endif ()
+
+ if (RunCMake_CXXModules_INSTALL)
+ set(prefix "${RunCMake_BINARY_DIR}/examples/${test_name}-install")
+ file(REMOVE_RECURSE "${prefix}")
+ list(APPEND RunCMake_TEST_OPTIONS
+ "-DCMAKE_INSTALL_PREFIX=${prefix}")
+ endif ()
+
+ list(APPEND RunCMake_TEST_OPTIONS
+ "-DCMake_TEST_MODULE_COMPILATION_RULES=${CMake_TEST_MODULE_COMPILATION_RULES}"
+ ${ARGN})
+ run_cmake("examples/${test_name}")
+ set(RunCMake_TEST_NO_CLEAN 1)
+ run_cmake_command("examples/${test_name}-build" "${CMAKE_COMMAND}" --build . --config Debug)
+ if (RunCMake_CXXModules_INSTALL)
+ run_cmake_command("examples/${test_name}-install" "${CMAKE_COMMAND}" --build . --target install --config Debug)
+ endif ()
+ run_cmake_command("examples/${test_name}-test" "${CMAKE_CTEST_COMMAND}" -C Debug --output-on-failure)
+endfunction ()
+
+string(REPLACE "," ";" CMake_TEST_MODULE_COMPILATION "${CMake_TEST_MODULE_COMPILATION}")
+
+# Tests which use named modules.
+if ("named" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(simple)
+ run_cxx_module_test(library library-static -DBUILD_SHARED_LIBS=OFF)
+ run_cxx_module_test(generated)
+ run_cxx_module_test(public-req-private)
+ run_cxx_module_test(deep-chain)
+endif ()
+
+# Tests which use named modules in shared libraries.
+if ("shared" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(library library-shared -DBUILD_SHARED_LIBS=ON)
+endif ()
+
+# Tests which use partitions.
+if ("partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(partitions)
+endif ()
+
+# Tests which use internal partitions.
+if ("internal_partitions" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(internal-partitions)
+endif ()
+
+# Tests which install BMIs
+if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(export-interface-build)
+ run_cxx_module_test(export-bmi-and-interface-build)
+endif ()
+
+# All of the following tests perform installation.
+set(RunCMake_CXXModules_INSTALL 1)
+
+# Tests which install BMIs
+if ("install_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(install-bmi)
+ run_cxx_module_test(install-bmi-and-interfaces)
+
+ if ("export_bmi" IN_LIST CMake_TEST_MODULE_COMPILATION)
+ run_cxx_module_test(export-interface-install)
+ run_cxx_module_test(export-bmi-and-interface-install)
+ endif ()
+endif ()
diff --git a/Tests/RunCMake/CXXModules/check-json.cmake b/Tests/RunCMake/CXXModules/check-json.cmake
new file mode 100644
index 0000000..19d0c8a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/check-json.cmake
@@ -0,0 +1,160 @@
+cmake_policy(PUSH)
+cmake_policy(SET CMP0057 NEW)
+
+function (json_placeholders in out)
+ string(REPLACE "<CONFIG>" "${CMAKE_BUILD_TYPE}" in "${in}")
+ if (RunCMake_GENERATOR_IS_MULTI_CONFIG)
+ string(REPLACE "<CONFIG_DIR>" "${CMAKE_BUILD_TYPE}/" in "${in}")
+ else ()
+ string(REPLACE "<CONFIG_DIR>" "" in "${in}")
+ endif ()
+ if (CMAKE_BUILD_TYPE)
+ string(REPLACE "<CONFIG_FORCE>" "${CMAKE_BUILD_TYPE}" in "${in}")
+ else ()
+ string(REPLACE "<CONFIG_FORCE>" "noconfig" in "${in}")
+ endif ()
+ string(REPLACE "<SOURCE_DIR>" "${RunCMake_SOURCE_DIR}" in "${in}")
+ string(REPLACE "<BINARY_DIR>" "${RunCMake_TEST_BINARY_DIR}" in "${in}")
+ set("${out}" "${in}" PARENT_SCOPE)
+endfunction ()
+
+function (check_json_value path actual_type expect_type actual_value expect_value)
+ if (NOT actual_type STREQUAL expect_type)
+ list(APPEND RunCMake_TEST_FAILED
+ "Type mismatch at ${path}: ${actual_type} vs. ${expect_type}")
+ return ()
+ endif ()
+
+ if (actual_type STREQUAL NULL)
+ # Nothing to check
+ elseif (actual_type STREQUAL BOOLEAN)
+ if (NOT actual_value STREQUAL expect_value)
+ list(APPEND RunCMake_TEST_FAILED
+ "Boolean mismatch at ${path}: ${actual_value} vs. ${expect_value}")
+ endif ()
+ elseif (actual_type STREQUAL NUMBER)
+ if (NOT actual_value EQUAL expect_value)
+ list(APPEND RunCMake_TEST_FAILED
+ "Number mismatch at ${path}: ${actual_value} vs. ${expect_value}")
+ endif ()
+ elseif (actual_type STREQUAL STRING)
+ # Allow some values to be ignored.
+ if (expect_value STREQUAL "<IGNORE>")
+ return ()
+ endif ()
+
+ json_placeholders("${expect_value}" expect_value_expanded)
+ if (NOT actual_value STREQUAL expect_value_expanded)
+ list(APPEND RunCMake_TEST_FAILED
+ "String mismatch at ${path}: ${actual_value} vs. ${expect_value_expanded}")
+ endif ()
+ elseif (actual_type STREQUAL ARRAY)
+ check_json_array("${path}" "${actual_value}" "${expect_value}")
+ elseif (actual_type STREQUAL OBJECT)
+ check_json_object("${path}" "${actual_value}" "${expect_value}")
+ endif ()
+endfunction ()
+
+# Check that two arrays are the same.
+function (check_json_array path actual expect)
+ string(JSON actual_len LENGTH "${actual}")
+ string(JSON expect_len LENGTH "${expect}")
+
+ set(iter_len "${actual_len}")
+ if (actual_len LESS expect_len)
+ list(APPEND RunCMake_TEST_FAILED
+ "Missing array items at ${path}")
+ elseif (expect_len LESS actual_len)
+ list(APPEND RunCMake_TEST_FAILED
+ "Extra array items at ${path}")
+ set(iter_len "${expect_len}")
+ endif ()
+
+ foreach (idx RANGE "${iter_len}")
+ if (idx EQUAL iter_len)
+ break ()
+ endif ()
+
+ set(new_path "${path}[${idx}]")
+ string(JSON actual_type TYPE "${actual}" "${idx}")
+ string(JSON expect_type TYPE "${expect}" "${idx}")
+ string(JSON actual_value GET "${actual}" "${idx}")
+ string(JSON expect_value GET "${expect}" "${idx}")
+ check_json_value("${new_path}" "${actual_type}" "${expect_type}" "${actual_value}" "${expect_value}")
+ endforeach ()
+endfunction ()
+
+# Check that two inner objects are the same.
+function (check_json_object path actual expect)
+ string(JSON actual_len LENGTH "${actual}")
+ string(JSON expect_len LENGTH "${expect}")
+
+ set(actual_keys "")
+ set(expect_keys "")
+ foreach (idx RANGE "${actual_len}")
+ if (idx EQUAL actual_len)
+ break ()
+ endif ()
+
+ string(JSON actual_key MEMBER "${actual}" "${idx}")
+ list(APPEND actual_keys "${actual_key}")
+ endforeach ()
+ foreach (idx RANGE "${expect_len}")
+ if (idx EQUAL expect_len)
+ break ()
+ endif ()
+
+ string(JSON expect_key MEMBER "${expect}" "${idx}")
+ list(APPEND expect_keys "${expect_key}")
+ endforeach ()
+
+ json_placeholders("${expect_keys}" expect_keys_expanded)
+
+ set(actual_keys_missed "${actual_keys}")
+ set(expect_keys_missed "${expect_keys}")
+
+ set(common_keys "")
+ set(expect_keys_stack "${expect_keys}")
+ while (expect_keys_stack)
+ list(POP_BACK expect_keys_stack expect_key)
+ json_placeholders("${expect_key}" expect_key_expanded)
+
+ if (expect_key_expanded IN_LIST actual_keys_missed AND
+ expect_key IN_LIST expect_keys_missed)
+ list(APPEND common_keys "${expect_key}")
+ endif ()
+
+ list(REMOVE_ITEM actual_keys_missed "${expect_key_expanded}")
+ list(REMOVE_ITEM expect_keys_missed "${expect_key}")
+ endwhile ()
+
+ if (actual_keys_missed)
+ string(REPLACE ";" ", " actual_keys_missed_text "${actual_keys_missed}")
+ list(APPEND RunCMake_TEST_FAILED
+ "Missing expected members at ${path}: ${actual_keys_missed_text}")
+ endif ()
+ if (expect_keys_missed)
+ string(REPLACE ";" ", " expect_keys_missed_text "${expect_keys_missed}")
+ list(APPEND RunCMake_TEST_FAILED
+ "Extra unexpected members at ${path}: ${expect_keys_missed_text}")
+ endif ()
+
+ foreach (key IN LISTS common_keys)
+ json_placeholders("${key}" key_expanded)
+ set(new_path "${path}.${key_expanded}")
+ string(JSON actual_type TYPE "${actual}" "${key_expanded}")
+ string(JSON expect_type TYPE "${expect}" "${key}")
+ string(JSON actual_value GET "${actual}" "${key_expanded}")
+ string(JSON expect_value GET "${expect}" "${key}")
+ check_json_value("${new_path}" "${actual_type}" "${expect_type}" "${actual_value}" "${expect_value}")
+ endforeach ()
+endfunction ()
+
+# Check that two JSON objects are the same.
+function (check_json actual expect)
+ check_json_object("" "${actual}" "${expect}")
+endfunction ()
+
+string(REPLACE ";" "; " RunCMake_TEST_FAILED "${RunCMake_TEST_FAILED}")
+
+cmake_policy(POP)
diff --git a/Tests/RunCMake/CXXModules/compiler_introspection.cmake b/Tests/RunCMake/CXXModules/compiler_introspection.cmake
new file mode 100644
index 0000000..7a2df3d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/compiler_introspection.cmake
@@ -0,0 +1,25 @@
+enable_language(CXX)
+
+set(info "")
+
+# See `Modules/Compiler/MSVC-CXX.cmake` for this. If there is explicitly no
+# default, the feature list is populated to be everything.
+if (DEFINED CMAKE_CXX_STANDARD_DEFAULT AND
+ CMAKE_CXX_STANDARD_DEFAULT STREQUAL "")
+ set(CMAKE_CXX_COMPILE_FEATURES "")
+endif ()
+
+# Detect if the environment forces a C++ standard, let the test selection know.
+set(forced_cxx_standard 0)
+if (CMAKE_CXX_FLAGS MATCHES "-std=")
+ set(forced_cxx_standard 1)
+endif ()
+
+# Forward information about the C++ compile features.
+string(APPEND info "\
+set(CMAKE_CXX_COMPILE_FEATURES \"${CMAKE_CXX_COMPILE_FEATURES}\")
+set(CMAKE_MAKE_PROGRAM \"${CMAKE_MAKE_PROGRAM}\")
+set(forced_cxx_standard \"${forced_cxx_standard}\")
+")
+
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/info.cmake" "${info}")
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi-and-interfaces.cmake b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi-and-interfaces.cmake
new file mode 100644
index 0000000..f99455b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi-and-interfaces.cmake
@@ -0,0 +1,22 @@
+function (check_for_bmi prefix destination name)
+ set(found 0)
+ foreach (ext IN ITEMS gcm)
+ if (EXISTS "${prefix}/${destination}/${name}.${ext}")
+ set(found 1)
+ break ()
+ endif ()
+ endforeach ()
+
+ if (NOT found)
+ message(SEND_ERROR
+ "Failed to find the ${name} BMI")
+ endif ()
+endfunction ()
+
+function (check_for_interface prefix destination subdir name)
+ set(found 0)
+ if (NOT EXISTS "${prefix}/${destination}/${subdir}/${name}")
+ message(SEND_ERROR
+ "Failed to find the ${name} module interface")
+ endif ()
+endfunction ()
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
new file mode 100644
index 0000000..91f3995
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/cxx-modules-find-bmi.cmake
@@ -0,0 +1,27 @@
+function (check_for_bmi prefix destination name)
+ set(found 0)
+ foreach (ext IN ITEMS gcm ifc)
+ if (EXISTS "${prefix}/${destination}/${name}.${ext}")
+ set(found 1)
+ break ()
+ endif ()
+ endforeach ()
+
+ if (NOT found)
+ message(SEND_ERROR
+ "Failed to find the ${name} BMI")
+ endif ()
+endfunction ()
+
+function (check_for_interface prefix destination subdir name)
+ set(found 0)
+ if (NOT EXISTS "${prefix}/${destination}/${subdir}/${name}")
+ message(SEND_ERROR
+ "Failed to find the ${name} module interface")
+ endif ()
+endfunction ()
+
+function (report_dirs prefix destination)
+ message("prefix: ${prefix}")
+ message("destination: ${destination}")
+endfunction ()
diff --git a/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake b/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake
new file mode 100644
index 0000000..381094e
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/cxx-modules-rules.cmake
@@ -0,0 +1,18 @@
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
+
+if (NOT EXISTS "${CMake_TEST_MODULE_COMPILATION_RULES}")
+ message(FATAL_ERROR
+ "The `CMake_TEST_MODULE_COMPILATION_RULES` file must be specified "
+ "for these tests to operate.")
+endif ()
+
+include("${CMake_TEST_MODULE_COMPILATION_RULES}")
+
+if (NOT CMake_TEST_CXXModules_UUID STREQUAL "a246741c-d067-4019-a8fb-3d16b0c9d1d3")
+ message(FATAL_ERROR
+ "The compilation rule file needs updated for changes in the test "
+ "suite. Please see the history for what needs to be updated.")
+endif ()
+
+include(CTest)
+enable_testing()
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt b/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt
new file mode 100644
index 0000000..515b240
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/CMakeLists.txt
@@ -0,0 +1,66 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_deep_chain CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(a STATIC)
+target_sources(a
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ a.cxx)
+target_compile_features(a PUBLIC cxx_std_20)
+
+add_library(b STATIC)
+target_sources(b
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ b.cxx)
+target_compile_features(b PUBLIC cxx_std_20)
+target_link_libraries(b PUBLIC a)
+
+add_library(c STATIC)
+target_sources(c
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ c.cxx)
+target_compile_features(c PUBLIC cxx_std_20)
+target_link_libraries(c PUBLIC b)
+
+add_library(d STATIC)
+target_sources(d
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ d.cxx)
+target_compile_features(d PUBLIC cxx_std_20)
+target_link_libraries(d PUBLIC c)
+
+add_library(e STATIC)
+target_sources(e
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ e.cxx)
+target_compile_features(e PUBLIC cxx_std_20)
+target_link_libraries(e PUBLIC d)
+
+add_executable(exe)
+target_link_libraries(exe PRIVATE e)
+target_sources(exe
+ PRIVATE
+ main.cxx)
+
+add_test(NAME exe COMMAND exe)
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx
new file mode 100644
index 0000000..9edaec9
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/a.cxx
@@ -0,0 +1,6 @@
+export module a;
+
+export int a()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx
new file mode 100644
index 0000000..38ab0c2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/b.cxx
@@ -0,0 +1,7 @@
+export module b;
+import a;
+
+export int b()
+{
+ return a();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx
new file mode 100644
index 0000000..580a458
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/c.cxx
@@ -0,0 +1,7 @@
+export module c;
+import b;
+
+export int c()
+{
+ return b();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx
new file mode 100644
index 0000000..78bc5ba
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/d.cxx
@@ -0,0 +1,7 @@
+export module d;
+import c;
+
+export int d()
+{
+ return c();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx
new file mode 100644
index 0000000..e019440
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/e.cxx
@@ -0,0 +1,7 @@
+export module e;
+import d;
+
+export int e()
+{
+ return d();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx b/Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx
new file mode 100644
index 0000000..0b7c15d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/deep-chain/main.cxx
@@ -0,0 +1,6 @@
+import e;
+
+int main(int argc, char* argv[])
+{
+ return e();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/CMakeLists.txt
new file mode 100644
index 0000000..a450b7e
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/CMakeLists.txt
@@ -0,0 +1,56 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_export_bmi_and_interfaces CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(export_bmi_and_interfaces STATIC)
+target_sources(export_bmi_and_interfaces
+ PRIVATE
+ forward.cxx
+ PRIVATE
+ FILE_SET modules_private TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ private.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(export_bmi_and_interfaces PUBLIC cxx_std_20)
+
+install(TARGETS export_bmi_and_interfaces
+ EXPORT CXXModules
+ FILE_SET modules DESTINATION "lib/cxx/miu"
+ CXX_MODULES_BMI DESTINATION "lib/cxx/bmi")
+export(EXPORT CXXModules
+ NAMESPACE CXXModules::
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/export_bmi_and_interfaces-targets.cmake"
+ CXX_MODULES_DIRECTORY "export_bmi_and_interfaces-cxx-modules")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_bmi_and_interfaces-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_bmi_and_interfaces-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME export_bmi_and_interfaces_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_source_dir=${CMAKE_CURRENT_SOURCE_DIR}"
+ "-Dexpected_binary_dir=${CMAKE_CURRENT_BINARY_DIR}"
+ "-Dexport_bmi_and_interfaces_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/forward.cxx
new file mode 100644
index 0000000..7f53271
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/forward.cxx
@@ -0,0 +1,6 @@
+import priv;
+
+int forwarding()
+{
+ return from_private();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/importable.cxx
new file mode 100644
index 0000000..e0b1872
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/importable.cxx
@@ -0,0 +1,8 @@
+export module importable;
+
+int forwarding();
+
+export int from_import()
+{
+ return forwarding();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/private.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/private.cxx
new file mode 100644
index 0000000..c5b719a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/private.cxx
@@ -0,0 +1,6 @@
+export module priv;
+
+export int from_private()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt
new file mode 100644
index 0000000..b814b3b
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-build/test/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_library NONE)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
+
+find_package(export_bmi_and_interfaces REQUIRED)
+
+if (NOT TARGET CXXModules::export_bmi_and_interfaces)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+get_property(file_sets TARGET CXXModules::export_bmi_and_interfaces
+ PROPERTY INTERFACE_CXX_MODULE_SETS)
+if (NOT file_sets STREQUAL "modules")
+ message(FATAL_ERROR
+ "Incorrect exported file sets in `CXXModules::export_bmi_and_interfaces`: `${file_sets}`")
+endif ()
+
+get_property(file_set_files TARGET CXXModules::export_bmi_and_interfaces
+ PROPERTY CXX_MODULE_SET_modules)
+if (NOT file_set_files STREQUAL "${expected_source_dir}/importable.cxx")
+ message(FATAL_ERROR
+ "Incorrect exported file set paths in CXXModules::export_bmi_and_interfaces`: `${file_set_files}`")
+endif ()
+
+get_property(imported_modules TARGET CXXModules::export_bmi_and_interfaces
+ PROPERTY IMPORTED_CXX_MODULES_DEBUG)
+if (NOT imported_modules MATCHES "importable=${expected_source_dir}/importable.cxx,${expected_binary_dir}/CMakeFiles/export_bmi_and_interfaces.dir(/Debug)?/importable.(gcm|pcm|ifc)")
+ message(FATAL_ERROR
+ "Incorrect exported modules in CXXModules::export_bmi_and_interfaces`: `${imported_modules}`")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/CMakeLists.txt
new file mode 100644
index 0000000..a5574fe
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/CMakeLists.txt
@@ -0,0 +1,59 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_export_bmi_and_interfaces CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(export_bmi_and_interfaces STATIC)
+target_sources(export_bmi_and_interfaces
+ PRIVATE
+ forward.cxx
+ PRIVATE
+ FILE_SET modules_private TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ private.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(export_bmi_and_interfaces PUBLIC cxx_std_20)
+
+install(TARGETS export_bmi_and_interfaces
+ EXPORT CXXModules
+ FILE_SET modules DESTINATION "lib/cxx/miu"
+ CXX_MODULES_BMI DESTINATION "lib/cxx/bmi")
+install(EXPORT CXXModules
+ NAMESPACE CXXModules::
+ DESTINATION "lib/cmake/export_bmi_and_interfaces"
+ FILE "export_bmi_and_interfaces-targets.cmake"
+ CXX_MODULES_DIRECTORY "export_bmi_and_interfaces-cxx-modules")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_bmi_and_interfaces-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_bmi_and_interfaces-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/export_bmi_and_interfaces-config.cmake"
+ DESTINATION "lib/cmake/export_bmi_and_interfaces")
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME export_bmi_and_interfaces_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_source_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
+ "-Dexpected_binary_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/bmi"
+ "-Dexport_bmi_and_interfaces_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_bmi_and_interfaces"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/forward.cxx
new file mode 100644
index 0000000..7f53271
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/forward.cxx
@@ -0,0 +1,6 @@
+import priv;
+
+int forwarding()
+{
+ return from_private();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/importable.cxx
new file mode 100644
index 0000000..e0b1872
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/importable.cxx
@@ -0,0 +1,8 @@
+export module importable;
+
+int forwarding();
+
+export int from_import()
+{
+ return forwarding();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/private.cxx b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/private.cxx
new file mode 100644
index 0000000..c5b719a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/private.cxx
@@ -0,0 +1,6 @@
+export module priv;
+
+export int from_private()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt
new file mode 100644
index 0000000..db0484d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-bmi-and-interface-install/test/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_library NONE)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
+
+find_package(export_bmi_and_interfaces REQUIRED)
+
+if (NOT TARGET CXXModules::export_bmi_and_interfaces)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+get_property(file_sets TARGET CXXModules::export_bmi_and_interfaces
+ PROPERTY INTERFACE_CXX_MODULE_SETS)
+if (NOT file_sets STREQUAL "modules")
+ message(FATAL_ERROR
+ "Incorrect exported file sets in `CXXModules::export_bmi_and_interfaces`: `${file_sets}`")
+endif ()
+
+get_property(file_set_files TARGET CXXModules::export_bmi_and_interfaces
+ PROPERTY CXX_MODULE_SET_modules)
+if (NOT file_set_files STREQUAL "${expected_source_dir}/importable.cxx")
+ message(FATAL_ERROR
+ "Incorrect exported file set paths in CXXModules::export_bmi_and_interfaces`: `${file_set_files}`")
+endif ()
+
+get_property(imported_modules TARGET CXXModules::export_bmi_and_interfaces
+ PROPERTY IMPORTED_CXX_MODULES_DEBUG)
+if (NOT imported_modules MATCHES "importable=${expected_source_dir}/importable.cxx,${expected_binary_dir}/importable.(gcm|pcm|ifc)")
+ message(FATAL_ERROR
+ "Incorrect exported modules in CXXModules::export_bmi_and_interfaces`: `${imported_modules}`")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build-stderr.txt b/Tests/RunCMake/CXXModules/examples/export-interface-build-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-build-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-build/CMakeLists.txt
new file mode 100644
index 0000000..80ddaf8
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-build/CMakeLists.txt
@@ -0,0 +1,53 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_export_interfaces CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(export_interfaces STATIC)
+target_sources(export_interfaces
+ PRIVATE
+ forward.cxx
+ PRIVATE
+ FILE_SET modules_private TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ private.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(export_interfaces PUBLIC cxx_std_20)
+
+install(TARGETS export_interfaces
+ EXPORT CXXModules
+ FILE_SET modules DESTINATION "lib/cxx/miu")
+export(EXPORT CXXModules
+ NAMESPACE CXXModules::
+ FILE "${CMAKE_CURRENT_BINARY_DIR}/export_interfaces-targets.cmake")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_interfaces-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_interfaces-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME export_interfaces_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_dir=${CMAKE_CURRENT_SOURCE_DIR}"
+ "-Dexport_interfaces_DIR=${CMAKE_CURRENT_BINARY_DIR}"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx
new file mode 100644
index 0000000..7f53271
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-build/forward.cxx
@@ -0,0 +1,6 @@
+import priv;
+
+int forwarding()
+{
+ return from_private();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx
new file mode 100644
index 0000000..e0b1872
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-build/importable.cxx
@@ -0,0 +1,8 @@
+export module importable;
+
+int forwarding();
+
+export int from_import()
+{
+ return forwarding();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx
new file mode 100644
index 0000000..c5b719a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-build/private.cxx
@@ -0,0 +1,6 @@
+export module priv;
+
+export int from_private()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt
new file mode 100644
index 0000000..6145210
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-build/test/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_library NONE)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
+
+find_package(export_interfaces REQUIRED)
+
+if (NOT TARGET CXXModules::export_interfaces)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+get_property(file_sets TARGET CXXModules::export_interfaces
+ PROPERTY INTERFACE_CXX_MODULE_SETS)
+if (NOT file_sets STREQUAL "modules")
+ message(FATAL_ERROR
+ "Incorrect exported file sets in `CXXModules::export_interfaces`: `${file_sets}`")
+endif ()
+
+get_property(file_set_files TARGET CXXModules::export_interfaces
+ PROPERTY CXX_MODULE_SET_modules)
+if (NOT file_set_files STREQUAL "${expected_dir}/importable.cxx")
+ message(FATAL_ERROR
+ "Incorrect exported file set paths in CXXModules::export_interfaces`: `${file_set_files}`")
+endif ()
+
+get_property(imported_modules_set TARGET CXXModules::export_interfaces
+ PROPERTY IMPORTED_CXX_MODULES_DEBUG SET)
+if (imported_modules_set)
+ message(FATAL_ERROR
+ "Unexpected C++ modules specified.")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install-stderr.txt b/Tests/RunCMake/CXXModules/examples/export-interface-install-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-install-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-install/CMakeLists.txt
new file mode 100644
index 0000000..1dfb6da
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-install/CMakeLists.txt
@@ -0,0 +1,56 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_export_interfaces CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(export_interfaces STATIC)
+target_sources(export_interfaces
+ PRIVATE
+ forward.cxx
+ PRIVATE
+ FILE_SET modules_private TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ private.cxx
+ PUBLIC
+ FILE_SET modules TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(export_interfaces PUBLIC cxx_std_20)
+
+install(TARGETS export_interfaces
+ EXPORT CXXModules
+ FILE_SET modules DESTINATION "lib/cxx/miu")
+install(EXPORT CXXModules
+ NAMESPACE CXXModules::
+ DESTINATION "lib/cmake/export_interfaces"
+ FILE "export_interfaces-targets.cmake")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/export_interfaces-config.cmake"
+ "include(\"\${CMAKE_CURRENT_LIST_DIR}/export_interfaces-targets.cmake\")
+set(\${CMAKE_FIND_PACKAGE_NAME}_FOUND 1)
+")
+install(FILES "${CMAKE_CURRENT_BINARY_DIR}/export_interfaces-config.cmake"
+ DESTINATION "lib/cmake/export_interfaces")
+
+set(generator
+ -G "${CMAKE_GENERATOR}")
+if (CMAKE_GENERATOR_TOOLSET)
+ list(APPEND generator
+ -T "${CMAKE_GENERATOR_TOOLSET}")
+endif ()
+if (CMAKE_GENERATOR_PLATFORM)
+ list(APPEND generator
+ -A "${CMAKE_GENERATOR_PLATFORM}")
+endif ()
+
+add_test(NAME export_interfaces_build
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dexpected_dir=${CMAKE_INSTALL_PREFIX}/lib/cxx/miu"
+ "-Dexport_interfaces_DIR=${CMAKE_INSTALL_PREFIX}/lib/cmake/export_interfaces"
+ ${generator}
+ -S "${CMAKE_CURRENT_SOURCE_DIR}/test"
+ -B "${CMAKE_CURRENT_BINARY_DIR}/test")
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx
new file mode 100644
index 0000000..7f53271
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-install/forward.cxx
@@ -0,0 +1,6 @@
+import priv;
+
+int forwarding()
+{
+ return from_private();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx
new file mode 100644
index 0000000..e0b1872
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-install/importable.cxx
@@ -0,0 +1,8 @@
+export module importable;
+
+int forwarding();
+
+export int from_import()
+{
+ return forwarding();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx b/Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx
new file mode 100644
index 0000000..c5b719a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-install/private.cxx
@@ -0,0 +1,6 @@
+export module priv;
+
+export int from_private()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt
new file mode 100644
index 0000000..6145210
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/export-interface-install/test/CMakeLists.txt
@@ -0,0 +1,32 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_library NONE)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
+
+find_package(export_interfaces REQUIRED)
+
+if (NOT TARGET CXXModules::export_interfaces)
+ message(FATAL_ERROR
+ "Missing imported target")
+endif ()
+
+get_property(file_sets TARGET CXXModules::export_interfaces
+ PROPERTY INTERFACE_CXX_MODULE_SETS)
+if (NOT file_sets STREQUAL "modules")
+ message(FATAL_ERROR
+ "Incorrect exported file sets in `CXXModules::export_interfaces`: `${file_sets}`")
+endif ()
+
+get_property(file_set_files TARGET CXXModules::export_interfaces
+ PROPERTY CXX_MODULE_SET_modules)
+if (NOT file_set_files STREQUAL "${expected_dir}/importable.cxx")
+ message(FATAL_ERROR
+ "Incorrect exported file set paths in CXXModules::export_interfaces`: `${file_set_files}`")
+endif ()
+
+get_property(imported_modules_set TARGET CXXModules::export_interfaces
+ PROPERTY IMPORTED_CXX_MODULES_DEBUG SET)
+if (imported_modules_set)
+ message(FATAL_ERROR
+ "Unexpected C++ modules specified.")
+endif ()
diff --git a/Tests/RunCMake/CXXModules/examples/generated-stderr.txt b/Tests/RunCMake/CXXModules/examples/generated-stderr.txt
new file mode 100644
index 0000000..b9bbf34
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/generated-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:12 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt
new file mode 100644
index 0000000..73f7ff7
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/generated/CMakeLists.txt
@@ -0,0 +1,23 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_generated CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+configure_file(
+ "${CMAKE_CURRENT_SOURCE_DIR}/importable.cxx.in"
+ "${CMAKE_CURRENT_BINARY_DIR}/importable.cxx"
+ COPYONLY)
+
+add_executable(generated)
+target_sources(generated
+ PRIVATE
+ main.cxx
+ PRIVATE
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_BINARY_DIR}"
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/importable.cxx")
+target_compile_features(generated PUBLIC cxx_std_20)
+
+add_test(NAME generated COMMAND generated)
diff --git a/Tests/RunCMake/CXXModules/examples/generated/importable.cxx.in b/Tests/RunCMake/CXXModules/examples/generated/importable.cxx.in
new file mode 100644
index 0000000..a9287d7
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/generated/importable.cxx.in
@@ -0,0 +1,5 @@
+export module importable;
+
+export int from_import() {
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/generated/main.cxx b/Tests/RunCMake/CXXModules/examples/generated/main.cxx
new file mode 100644
index 0000000..feb38d2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/generated/main.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+ return from_import();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces-stderr.txt b/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/CMakeLists.txt
new file mode 100644
index 0000000..efaca0e
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/CMakeLists.txt
@@ -0,0 +1,27 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_install_bmi_and_interfaces CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(install_bmi_and_interfaces STATIC)
+target_sources(install_bmi_and_interfaces
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(install_bmi_and_interfaces PUBLIC cxx_std_20)
+
+install(TARGETS install_bmi_and_interfaces
+ ARCHIVE DESTINATION "lib"
+ CXX_MODULES_BMI DESTINATION "lib/cxx/bmi"
+ FILE_SET CXX_MODULES DESTINATION "lib/cxx/miu")
+
+add_test(NAME check-for-bmi
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dprefix=${CMAKE_INSTALL_PREFIX}"
+ "-Dbmi_destination=lib/cxx/bmi"
+ "-Dfs_destination=lib/cxx/miu"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/check-for-bmi.cmake")
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/check-for-bmi.cmake b/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/check-for-bmi.cmake
new file mode 100644
index 0000000..a8ff1ad
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/check-for-bmi.cmake
@@ -0,0 +1,7 @@
+include("${CMAKE_CURRENT_LIST_DIR}/../cxx-modules-find-bmi.cmake")
+
+report_dirs("${prefix}" "${bmi_destination}")
+check_for_bmi("${prefix}" "${bmi_destination}" importable)
+
+report_dirs("${prefix}" "${fs_destination}")
+check_for_interface("${prefix}" "${fs_destination}" "" importable.cxx)
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/importable.cxx b/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/importable.cxx
new file mode 100644
index 0000000..607680a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/install-bmi-and-interfaces/importable.cxx
@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi-stderr.txt b/Tests/RunCMake/CXXModules/examples/install-bmi-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/install-bmi-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/install-bmi/CMakeLists.txt
new file mode 100644
index 0000000..4e039f9
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/install-bmi/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_install_bmi CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(install_bmi STATIC)
+target_sources(install_bmi
+ PUBLIC
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(install_bmi PUBLIC cxx_std_20)
+
+install(TARGETS install_bmi
+ ARCHIVE DESTINATION "lib"
+ CXX_MODULES_BMI DESTINATION "lib/cxx/bmi")
+
+add_test(NAME check-for-bmi
+ COMMAND
+ "${CMAKE_COMMAND}"
+ "-Dprefix=${CMAKE_INSTALL_PREFIX}"
+ "-Ddestination=lib/cxx/bmi"
+ -P "${CMAKE_CURRENT_SOURCE_DIR}/check-for-bmi.cmake")
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi/check-for-bmi.cmake b/Tests/RunCMake/CXXModules/examples/install-bmi/check-for-bmi.cmake
new file mode 100644
index 0000000..ff84ed6
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/install-bmi/check-for-bmi.cmake
@@ -0,0 +1,4 @@
+include("${CMAKE_CURRENT_LIST_DIR}/../cxx-modules-find-bmi.cmake")
+
+report_dirs("${prefix}" "${destination}")
+check_for_bmi("${prefix}" "${destination}" importable)
diff --git a/Tests/RunCMake/CXXModules/examples/install-bmi/importable.cxx b/Tests/RunCMake/CXXModules/examples/install-bmi/importable.cxx
new file mode 100644
index 0000000..607680a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/install-bmi/importable.cxx
@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions-stderr.txt b/Tests/RunCMake/CXXModules/examples/internal-partitions-stderr.txt
new file mode 100644
index 0000000..4652aec
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/internal-partitions-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/internal-partitions/CMakeLists.txt
new file mode 100644
index 0000000..f5e9d94
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/internal-partitions/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_internal_partitions CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+include(GenerateExportHeader)
+
+add_library(internal-partitions)
+generate_export_header(internal-partitions)
+target_sources(internal-partitions
+ PUBLIC
+ FILE_SET HEADERS
+ BASE_DIRS
+ "${CMAKE_CURRENT_BINARY_DIR}"
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/internal-partitions_export.h"
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx
+ partition.cxx)
+target_compile_features(internal-partitions PUBLIC cxx_std_20)
+
+add_executable(exe)
+target_link_libraries(exe PRIVATE internal-partitions)
+target_sources(exe
+ PRIVATE
+ main.cxx)
+
+add_test(NAME exe COMMAND exe)
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx b/Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx
new file mode 100644
index 0000000..b872ae9
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/internal-partitions/importable.cxx
@@ -0,0 +1,9 @@
+export module importable;
+import : internal_partition;
+
+#include "internal-partitions_export.h"
+
+export INTERNAL_PARTITIONS_EXPORT int from_import()
+{
+ return from_partition();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/main.cxx b/Tests/RunCMake/CXXModules/examples/internal-partitions/main.cxx
new file mode 100644
index 0000000..feb38d2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/internal-partitions/main.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+ return from_import();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/internal-partitions/partition.cxx b/Tests/RunCMake/CXXModules/examples/internal-partitions/partition.cxx
new file mode 100644
index 0000000..b15f53c
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/internal-partitions/partition.cxx
@@ -0,0 +1,6 @@
+module importable : internal_partition;
+
+int from_partition()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/library-shared-stderr.txt b/Tests/RunCMake/CXXModules/examples/library-shared-stderr.txt
new file mode 100644
index 0000000..4652aec
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/library-shared-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/library-static-stderr.txt b/Tests/RunCMake/CXXModules/examples/library-static-stderr.txt
new file mode 100644
index 0000000..4652aec
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/library-static-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/library/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/library/CMakeLists.txt
new file mode 100644
index 0000000..27fd94f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/library/CMakeLists.txt
@@ -0,0 +1,30 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_library CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+include(GenerateExportHeader)
+
+add_library(library)
+generate_export_header(library)
+target_sources(library
+ PUBLIC
+ FILE_SET HEADERS
+ BASE_DIRS
+ "${CMAKE_CURRENT_BINARY_DIR}"
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/library_export.h"
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(library PUBLIC cxx_std_20)
+
+add_executable(exe)
+target_link_libraries(exe PRIVATE library)
+target_sources(exe
+ PRIVATE
+ main.cxx)
+
+add_test(NAME exe COMMAND exe)
diff --git a/Tests/RunCMake/CXXModules/examples/library/importable.cxx b/Tests/RunCMake/CXXModules/examples/library/importable.cxx
new file mode 100644
index 0000000..72ed0df
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/library/importable.cxx
@@ -0,0 +1,8 @@
+export module importable;
+
+#include "library_export.h"
+
+export LIBRARY_EXPORT int from_import()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/library/main.cxx b/Tests/RunCMake/CXXModules/examples/library/main.cxx
new file mode 100644
index 0000000..feb38d2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/library/main.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+ return from_import();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/partitions-stderr.txt b/Tests/RunCMake/CXXModules/examples/partitions-stderr.txt
new file mode 100644
index 0000000..4652aec
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/partitions-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:10 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/partitions/CMakeLists.txt
new file mode 100644
index 0000000..3a7b0d4
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/partitions/CMakeLists.txt
@@ -0,0 +1,31 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_partitions CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+include(GenerateExportHeader)
+
+add_library(partitions)
+generate_export_header(partitions)
+target_sources(partitions
+ PUBLIC
+ FILE_SET HEADERS
+ BASE_DIRS
+ "${CMAKE_CURRENT_BINARY_DIR}"
+ FILES
+ "${CMAKE_CURRENT_BINARY_DIR}/partitions_export.h"
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx
+ partition.cxx)
+target_compile_features(partitions PUBLIC cxx_std_20)
+
+add_executable(exe)
+target_link_libraries(exe PRIVATE partitions)
+target_sources(exe
+ PRIVATE
+ main.cxx)
+
+add_test(NAME exe COMMAND exe)
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/importable.cxx b/Tests/RunCMake/CXXModules/examples/partitions/importable.cxx
new file mode 100644
index 0000000..d0ac2f4
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/partitions/importable.cxx
@@ -0,0 +1,9 @@
+export module importable;
+export import : partition;
+
+#include "partitions_export.h"
+
+export PARTITIONS_EXPORT int from_import()
+{
+ return from_partition();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/main.cxx b/Tests/RunCMake/CXXModules/examples/partitions/main.cxx
new file mode 100644
index 0000000..c5b78c9
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/partitions/main.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+ return from_import() + from_partition();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/partitions/partition.cxx b/Tests/RunCMake/CXXModules/examples/partitions/partition.cxx
new file mode 100644
index 0000000..a47a4fd
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/partitions/partition.cxx
@@ -0,0 +1,8 @@
+export module importable : partition;
+
+#include "partitions_export.h"
+
+export PARTITIONS_EXPORT int from_partition()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private-build-result.txt b/Tests/RunCMake/CXXModules/examples/public-req-private-build-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/public-req-private-build-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private-build-stdout.txt b/Tests/RunCMake/CXXModules/examples/public-req-private-build-stdout.txt
new file mode 100644
index 0000000..b5f1c55
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/public-req-private-build-stdout.txt
@@ -0,0 +1 @@
+CMake Error: Public C\+\+ module source `.*/Tests/RunCMake/CXXModules/examples/public-req-private/pub.cxx` requires the `priv` C\+\+ module which is provided by a private source
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private-stderr.txt b/Tests/RunCMake/CXXModules/examples/public-req-private-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/public-req-private-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/public-req-private/CMakeLists.txt
new file mode 100644
index 0000000..600fec4
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/public-req-private/CMakeLists.txt
@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_public_req_private CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_library(public_req_private)
+target_sources(public_req_private
+ PRIVATE
+ FILE_SET private TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ priv.cxx
+ PUBLIC
+ FILE_SET public TYPE CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ pub.cxx)
+target_compile_features(public_req_private PUBLIC cxx_std_20)
+
+add_test(NAME cmake-version COMMAND "${CMAKE_COMMAND}" --version)
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private/priv.cxx b/Tests/RunCMake/CXXModules/examples/public-req-private/priv.cxx
new file mode 100644
index 0000000..7c000b7
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/public-req-private/priv.cxx
@@ -0,0 +1,6 @@
+export module priv;
+
+export int g()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/public-req-private/pub.cxx b/Tests/RunCMake/CXXModules/examples/public-req-private/pub.cxx
new file mode 100644
index 0000000..6ff2d23
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/public-req-private/pub.cxx
@@ -0,0 +1,8 @@
+export module pub;
+
+import priv;
+
+export int f()
+{
+ return g();
+}
diff --git a/Tests/RunCMake/CXXModules/examples/simple-stderr.txt b/Tests/RunCMake/CXXModules/examples/simple-stderr.txt
new file mode 100644
index 0000000..5e4392a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/simple-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) at CMakeLists.txt:7 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Warning \(dev\):
+ C\+\+20 modules support via CMAKE_EXPERIMENTAL_CXX_MODULE_DYNDEP is
+ experimental. It is meant only for compiler developers to try.
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/CXXModules/examples/simple/CMakeLists.txt b/Tests/RunCMake/CXXModules/examples/simple/CMakeLists.txt
new file mode 100644
index 0000000..442e425
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/simple/CMakeLists.txt
@@ -0,0 +1,18 @@
+cmake_minimum_required(VERSION 3.24)
+project(cxx_modules_simple CXX)
+
+include("${CMAKE_SOURCE_DIR}/../cxx-modules-rules.cmake")
+
+add_executable(simple)
+target_sources(simple
+ PRIVATE
+ main.cxx
+ PRIVATE
+ FILE_SET CXX_MODULES
+ BASE_DIRS
+ "${CMAKE_CURRENT_SOURCE_DIR}"
+ FILES
+ importable.cxx)
+target_compile_features(simple PUBLIC cxx_std_20)
+
+add_test(NAME simple COMMAND simple)
diff --git a/Tests/RunCMake/CXXModules/examples/simple/importable.cxx b/Tests/RunCMake/CXXModules/examples/simple/importable.cxx
new file mode 100644
index 0000000..607680a
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/simple/importable.cxx
@@ -0,0 +1,6 @@
+export module importable;
+
+export int from_import()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/examples/simple/main.cxx b/Tests/RunCMake/CXXModules/examples/simple/main.cxx
new file mode 100644
index 0000000..feb38d2
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/examples/simple/main.cxx
@@ -0,0 +1,6 @@
+import importable;
+
+int main(int argc, char* argv[])
+{
+ return from_import();
+}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json
new file mode 100644
index 0000000..65f0759
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-private.json
@@ -0,0 +1,45 @@
+{
+ "bmi-installation": {
+ "destination": "lib/cxx/modules/private/<CONFIG>",
+ "message-level": "MESSAGE_LAZY",
+ "permissions": " OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ",
+ "script-location": "<BINARY_DIR>/CMakeFiles/ninja-bmi-install-private.dir/install-cxx-module-bmi-<CONFIG_FORCE>.cmake"
+ },
+ "compiler-id": "<IGNORE>",
+ "config": "<CONFIG>",
+ "cxx-modules": {
+ "CMakeFiles/ninja-bmi-install-private.dir/sources/module-internal-part.cxx.o": {
+ "destination": null,
+ "name": "internal_partitions",
+ "relative-directory": "sources",
+ "source": "<SOURCE_DIR>/sources/module-internal-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ },
+ "CMakeFiles/ninja-bmi-install-private.dir/sources/module-part.cxx.o": {
+ "destination": null,
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ },
+ "CMakeFiles/ninja-bmi-install-private.dir/sources/module.cxx.o": {
+ "destination": null,
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ }
+ },
+ "dir-cur-bld": "<BINARY_DIR>",
+ "dir-cur-src": "<SOURCE_DIR>",
+ "dir-top-bld": "<BINARY_DIR>",
+ "dir-top-src": "<SOURCE_DIR>",
+ "exports": [],
+ "include-dirs": [],
+ "language": "CXX",
+ "linked-target-dirs": [],
+ "module-dir": "<BINARY_DIR>/CMakeFiles/ninja-bmi-install-private.dir"
+}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json
new file mode 100644
index 0000000..9c8a895
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoBMIInstall-public.json
@@ -0,0 +1,45 @@
+{
+ "bmi-installation": {
+ "destination": "lib/cxx/modules/<CONFIG>",
+ "message-level": "",
+ "permissions": "",
+ "script-location": "<BINARY_DIR>/CMakeFiles/ninja-bmi-install-public.dir/install-cxx-module-bmi-noconfig.cmake"
+ },
+ "compiler-id": "<IGNORE>",
+ "config": "<CONFIG>",
+ "cxx-modules": {
+ "CMakeFiles/ninja-bmi-install-public.dir/sources/module-internal-part.cxx.o": {
+ "destination": "lib/cxx/internals",
+ "name": "internal_partitions",
+ "relative-directory": "sources",
+ "source": "<SOURCE_DIR>/sources/module-internal-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ },
+ "CMakeFiles/ninja-bmi-install-public.dir/sources/module-part.cxx.o": {
+ "destination": "lib/cxx",
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ },
+ "CMakeFiles/ninja-bmi-install-public.dir/sources/module.cxx.o": {
+ "destination": "lib/cxx",
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ }
+ },
+ "dir-cur-bld": "<BINARY_DIR>",
+ "dir-cur-src": "<SOURCE_DIR>",
+ "dir-top-bld": "<BINARY_DIR>",
+ "dir-top-src": "<SOURCE_DIR>",
+ "exports": [],
+ "include-dirs": [],
+ "language": "CXX",
+ "linked-target-dirs": [],
+ "module-dir": "<BINARY_DIR>/CMakeFiles/ninja-bmi-install-public.dir"
+}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json
new file mode 100644
index 0000000..0545981
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-private.json
@@ -0,0 +1,73 @@
+{
+ "bmi-installation": null,
+ "compiler-id": "<IGNORE>",
+ "config": "<CONFIG>",
+ "cxx-modules": {
+ "CMakeFiles/ninja-exports-private.dir/sources/module-internal-part.cxx.o": {
+ "destination": null,
+ "name": "internal_partitions",
+ "relative-directory": "sources",
+ "source": "<SOURCE_DIR>/sources/module-internal-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ },
+ "CMakeFiles/ninja-exports-private.dir/sources/module-part.cxx.o": {
+ "destination": null,
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ },
+ "CMakeFiles/ninja-exports-private.dir/sources/module.cxx.o": {
+ "destination": null,
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ }
+ },
+ "dir-cur-bld": "<BINARY_DIR>",
+ "dir-cur-src": "<SOURCE_DIR>",
+ "dir-top-bld": "<BINARY_DIR>",
+ "dir-top-src": "<SOURCE_DIR>",
+ "exports": [
+ {
+ "cxx-module-info-dir" : "cxx-modules",
+ "destination" : "lib/cmake/export1",
+ "export-name" : "with-private",
+ "export-prefix" : "<BINARY_DIR>/CMakeFiles/Export/d2e2673818fd2bd8c45c0e3ed0e38fcd",
+ "install" : true,
+ "namespace" : "export1::"
+ },
+ {
+ "cxx-module-info-dir" : "cxx-modules",
+ "destination" : "lib/cmake/export2",
+ "export-name" : "with-private",
+ "export-prefix" : "<BINARY_DIR>/CMakeFiles/Export/28cd47cb4c96ad5cadaa3fb1b0201ae8",
+ "install" : true,
+ "namespace" : ""
+ },
+ {
+ "cxx-module-info-dir" : "cxx-modules",
+ "destination" : "<BINARY_DIR>/lib/cmake/export1",
+ "export-name" : "with-private",
+ "export-prefix" : "<BINARY_DIR>/lib/cmake/export1",
+ "install" : false,
+ "namespace" : "export1::"
+ },
+ {
+ "cxx-module-info-dir" : "cxx-modules",
+ "destination" : "<BINARY_DIR>/lib/cmake/export2",
+ "export-name" : "with-private",
+ "export-prefix" : "<BINARY_DIR>/lib/cmake/export2",
+ "install" : false,
+ "namespace" : ""
+ }
+ ],
+ "include-dirs": [],
+ "language": "CXX",
+ "linked-target-dirs": [],
+ "module-dir": "<BINARY_DIR>/CMakeFiles/ninja-exports-private.dir"
+}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json
new file mode 100644
index 0000000..adc3ae3
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoExport-public.json
@@ -0,0 +1,73 @@
+{
+ "bmi-installation": null,
+ "compiler-id": "<IGNORE>",
+ "config": "<CONFIG>",
+ "cxx-modules": {
+ "CMakeFiles/ninja-exports-public.dir/sources/module-internal-part.cxx.o": {
+ "destination": "lib/cxx/internals",
+ "name": "internal_partitions",
+ "relative-directory": "sources",
+ "source": "<SOURCE_DIR>/sources/module-internal-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ },
+ "CMakeFiles/ninja-exports-public.dir/sources/module-part.cxx.o": {
+ "destination": "lib/cxx",
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ },
+ "CMakeFiles/ninja-exports-public.dir/sources/module.cxx.o": {
+ "destination": "lib/cxx",
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ }
+ },
+ "dir-cur-bld": "<BINARY_DIR>",
+ "dir-cur-src": "<SOURCE_DIR>",
+ "dir-top-bld": "<BINARY_DIR>",
+ "dir-top-src": "<SOURCE_DIR>",
+ "exports": [
+ {
+ "cxx-module-info-dir" : "cxx-modules",
+ "destination" : "lib/cmake/export1",
+ "export-name" : "with-public",
+ "export-prefix" : "<BINARY_DIR>/CMakeFiles/Export/d2e2673818fd2bd8c45c0e3ed0e38fcd",
+ "install" : true,
+ "namespace" : "export1::"
+ },
+ {
+ "cxx-module-info-dir" : "cxx-modules",
+ "destination" : "lib/cmake/export2",
+ "export-name" : "with-public",
+ "export-prefix" : "<BINARY_DIR>/CMakeFiles/Export/28cd47cb4c96ad5cadaa3fb1b0201ae8",
+ "install" : true,
+ "namespace" : ""
+ },
+ {
+ "cxx-module-info-dir" : "cxx-modules",
+ "destination" : "<BINARY_DIR>/lib/cmake/export1",
+ "export-name" : "with-public",
+ "export-prefix" : "<BINARY_DIR>/lib/cmake/export1",
+ "install" : false,
+ "namespace" : "export1::"
+ },
+ {
+ "cxx-module-info-dir" : "cxx-modules",
+ "destination" : "<BINARY_DIR>/lib/cmake/export2",
+ "export-name" : "with-public",
+ "export-prefix" : "<BINARY_DIR>/lib/cmake/export2",
+ "install" : false,
+ "namespace" : ""
+ }
+ ],
+ "include-dirs": [],
+ "language": "CXX",
+ "linked-target-dirs": [],
+ "module-dir": "<BINARY_DIR>/CMakeFiles/ninja-exports-public.dir"
+}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json
new file mode 100644
index 0000000..9ba6568
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-private.json
@@ -0,0 +1,40 @@
+{
+ "bmi-installation": null,
+ "compiler-id": "<IGNORE>",
+ "config": "<CONFIG>",
+ "cxx-modules": {
+ "CMakeFiles/ninja-file-sets-private.dir/sources/module-internal-part.cxx.o": {
+ "destination": null,
+ "name": "internal_partitions",
+ "relative-directory": "sources",
+ "source": "<SOURCE_DIR>/sources/module-internal-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ },
+ "CMakeFiles/ninja-file-sets-private.dir/sources/module-part.cxx.o": {
+ "destination": null,
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ },
+ "CMakeFiles/ninja-file-sets-private.dir/sources/module.cxx.o": {
+ "destination": null,
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PRIVATE"
+ }
+ },
+ "dir-cur-bld": "<BINARY_DIR>",
+ "dir-cur-src": "<SOURCE_DIR>",
+ "dir-top-bld": "<BINARY_DIR>",
+ "dir-top-src": "<SOURCE_DIR>",
+ "exports": [],
+ "include-dirs": [],
+ "language": "CXX",
+ "linked-target-dirs": [],
+ "module-dir": "<BINARY_DIR>/CMakeFiles/ninja-file-sets-private.dir"
+}
diff --git a/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json
new file mode 100644
index 0000000..46e2cbf
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/expect/NinjaDependInfoFileSet-public.json
@@ -0,0 +1,40 @@
+{
+ "bmi-installation": null,
+ "compiler-id": "<IGNORE>",
+ "config": "<CONFIG>",
+ "cxx-modules": {
+ "CMakeFiles/ninja-file-sets-public.dir/<CONFIG_DIR>sources/module-internal-part.cxx.o": {
+ "destination": "lib/cxx/internals",
+ "name": "internal_partitions",
+ "relative-directory": "sources",
+ "source": "<SOURCE_DIR>/sources/module-internal-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ },
+ "CMakeFiles/ninja-file-sets-public.dir/<CONFIG_DIR>sources/module-part.cxx.o": {
+ "destination": "lib/cxx",
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module-part.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ },
+ "CMakeFiles/ninja-file-sets-public.dir/<CONFIG_DIR>sources/module.cxx.o": {
+ "destination": "lib/cxx",
+ "name": "modules",
+ "relative-directory": "",
+ "source": "<SOURCE_DIR>/sources/module.cxx",
+ "type": "CXX_MODULES",
+ "visibility": "PUBLIC"
+ }
+ },
+ "dir-cur-bld": "<BINARY_DIR>",
+ "dir-cur-src": "<SOURCE_DIR>",
+ "dir-top-bld": "<BINARY_DIR>",
+ "dir-top-src": "<SOURCE_DIR>",
+ "exports": [],
+ "include-dirs": [],
+ "language": "CXX",
+ "linked-target-dirs": [],
+ "module-dir": "<BINARY_DIR>/CMakeFiles/ninja-file-sets-public.dir"
+}
diff --git a/Tests/RunCMake/CXXModules/sources/c-anchor.c b/Tests/RunCMake/CXXModules/sources/c-anchor.c
new file mode 100644
index 0000000..c782188
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/c-anchor.c
@@ -0,0 +1,4 @@
+int c_anchor()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/sources/cxx-anchor.cxx b/Tests/RunCMake/CXXModules/sources/cxx-anchor.cxx
new file mode 100644
index 0000000..9c94ec1
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/cxx-anchor.cxx
@@ -0,0 +1,4 @@
+int cxx_anchor()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/sources/module-header.h b/Tests/RunCMake/CXXModules/sources/module-header.h
new file mode 100644
index 0000000..982617e
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/module-header.h
@@ -0,0 +1,9 @@
+#ifndef module_header_h
+#define module_header_h
+
+inline int h()
+{
+ return 0;
+}
+
+#endif
diff --git a/Tests/RunCMake/CXXModules/sources/module-impl.cxx b/Tests/RunCMake/CXXModules/sources/module-impl.cxx
new file mode 100644
index 0000000..4718999
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/module-impl.cxx
@@ -0,0 +1,6 @@
+module M;
+
+int f()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/sources/module-internal-part-impl.cxx b/Tests/RunCMake/CXXModules/sources/module-internal-part-impl.cxx
new file mode 100644
index 0000000..be77b0d
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/module-internal-part-impl.cxx
@@ -0,0 +1,11 @@
+#ifdef _MSC_VER
+// Only MSVC supports this pattern.
+module M : internal_part;
+#else
+module M;
+#endif
+
+int i()
+{
+ return 0;
+}
diff --git a/Tests/RunCMake/CXXModules/sources/module-internal-part.cxx b/Tests/RunCMake/CXXModules/sources/module-internal-part.cxx
new file mode 100644
index 0000000..fa82afb
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/module-internal-part.cxx
@@ -0,0 +1,3 @@
+module M : internal_part;
+
+int i();
diff --git a/Tests/RunCMake/CXXModules/sources/module-part-impl.cxx b/Tests/RunCMake/CXXModules/sources/module-part-impl.cxx
new file mode 100644
index 0000000..46d5d9f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/module-part-impl.cxx
@@ -0,0 +1,13 @@
+#ifdef _MSC_VER
+// Only MSVC supports this pattern.
+module M : part;
+#else
+module M;
+#endif
+
+import M : internal_part;
+
+int p()
+{
+ return i();
+}
diff --git a/Tests/RunCMake/CXXModules/sources/module-part.cxx b/Tests/RunCMake/CXXModules/sources/module-part.cxx
new file mode 100644
index 0000000..137c16f
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/module-part.cxx
@@ -0,0 +1,3 @@
+export module M : part;
+
+int p();
diff --git a/Tests/RunCMake/CXXModules/sources/module-use.cxx b/Tests/RunCMake/CXXModules/sources/module-use.cxx
new file mode 100644
index 0000000..2d060cd
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/module-use.cxx
@@ -0,0 +1,6 @@
+import M;
+
+int main(int argc, char* argv[])
+{
+ return f() + p();
+}
diff --git a/Tests/RunCMake/CXXModules/sources/module.cxx b/Tests/RunCMake/CXXModules/sources/module.cxx
new file mode 100644
index 0000000..a631354
--- /dev/null
+++ b/Tests/RunCMake/CXXModules/sources/module.cxx
@@ -0,0 +1,5 @@
+export module M;
+export import M : part;
+import M : internal_part;
+
+int f();
diff --git a/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt b/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt
index dc2c3ad..9a1ba04 100644
--- a/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt
+++ b/Tests/RunCMake/CheckIPOSupported/default-lang-none-stderr.txt
@@ -1,6 +1,6 @@
^CMake Error at .*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(message\):
- IPO is not supported \(no C/CXX/Fortran languages found in ENABLED_LANGUAGES
- global property\)\.
+ IPO is not supported \(no C/CXX/CUDA/Fortran languages found in
+ ENABLED_LANGUAGES global property\)\.
Call Stack \(most recent call first\):
.*/Modules/CheckIPOSupported\.cmake:[0-9]+ \(_ipo_not_supported\)
default-lang-none\.cmake:[0-9]+ \(check_ipo_supported\)
diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
index 6a932f1..1452c9b 100644
--- a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
+++ b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
@@ -1 +1 @@
-^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":4}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"version":{.*}}$
+^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":4}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]},{"kind":"toolchains","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":false,"tls":(true|false),"version":{.*}}$
diff --git a/Tests/RunCMake/CommandLine/E_env-equal.cmake b/Tests/RunCMake/CommandLine/E_env-equal.cmake
new file mode 100644
index 0000000..3f18bb6
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env-equal.cmake
@@ -0,0 +1,15 @@
+if (NOT DEFINED ENV{TEST_ENV_EXPECTED})
+ if (NOT DEFINED ENV{TEST_ENV})
+ message(STATUS "TEST_ENV is correctly not set in environment")
+ else ()
+ message(FATAL_ERROR "TEST_ENV is incorrectly set in environment")
+ endif ()
+else ()
+ if (NOT DEFINED ENV{TEST_ENV})
+ message(FATAL_ERROR "TEST_ENV is incorrectly not set in environment")
+ elseif ("$ENV{TEST_ENV}" STREQUAL "$ENV{TEST_ENV_EXPECTED}")
+ message(STATUS "TEST_ENV is correctly set in environment: $ENV{TEST_ENV}")
+ else ()
+ message(FATAL_ERROR "TEST_ENV is incorrectly set in environment!\n\tactual: $ENV{TEST_ENV}\n\texpected: $ENV{TEST_ENV_EXPECTED}")
+ endif ()
+endif ()
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-bad-operation-result.txt b/Tests/RunCMake/CommandLine/E_env_modify-bad-operation-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-bad-operation-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-bad-operation-stderr.txt b/Tests/RunCMake/CommandLine/E_env_modify-bad-operation-stderr.txt
new file mode 100644
index 0000000..ccfdeab
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-bad-operation-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error: Error: Unrecognized environment manipulation argument: unknown
+
+cmake -E env: invalid parameter to --modify: TEST_ENV=unknown:$
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-cmake_list-stdout.txt b/Tests/RunCMake/CommandLine/E_env_modify-cmake_list-stdout.txt
new file mode 100644
index 0000000..ad42f56
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-cmake_list-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly set in environment: exp;ect;ed$
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-path_list-stdout.txt b/Tests/RunCMake/CommandLine/E_env_modify-path_list-stdout.txt
new file mode 100644
index 0000000..49572a3
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-path_list-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly set in environment: exp[;:]ect[;:]ed$
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-reset-stdout.txt b/Tests/RunCMake/CommandLine/E_env_modify-reset-stdout.txt
new file mode 100644
index 0000000..a60f1bf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-reset-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly set in environment: expected$
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-reset-to-unset-stdout.txt b/Tests/RunCMake/CommandLine/E_env_modify-reset-to-unset-stdout.txt
new file mode 100644
index 0000000..a1d5c01
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-reset-to-unset-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly not set in environment$
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-set-stdout.txt b/Tests/RunCMake/CommandLine/E_env_modify-set-stdout.txt
new file mode 100644
index 0000000..feff117
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-set-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly set in environment: 1$
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-string-stdout.txt b/Tests/RunCMake/CommandLine/E_env_modify-string-stdout.txt
new file mode 100644
index 0000000..a60f1bf
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-string-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly set in environment: expected$
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-unset-stdout.txt b/Tests/RunCMake/CommandLine/E_env_modify-unset-stdout.txt
new file mode 100644
index 0000000..a1d5c01
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-unset-stdout.txt
@@ -0,0 +1 @@
+^-- TEST_ENV is correctly not set in environment$
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-with-double-dash-result.txt b/Tests/RunCMake/CommandLine/E_env_modify-with-double-dash-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-with-double-dash-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-without-double-dash-result.txt b/Tests/RunCMake/CommandLine/E_env_modify-without-double-dash-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-without-double-dash-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/CommandLine/E_env_modify-without-double-dash-stderr.txt b/Tests/RunCMake/CommandLine/E_env_modify-without-double-dash-stderr.txt
new file mode 100644
index 0000000..8d98f9d
--- /dev/null
+++ b/Tests/RunCMake/CommandLine/E_env_modify-without-double-dash-stderr.txt
@@ -0,0 +1 @@
+.*
diff --git a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
index fc05b2d..7da0f8d 100644
--- a/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CommandLine/RunCMakeTest.cmake
@@ -744,6 +744,10 @@ run_cmake_command(E_cat-without-double-dash ${CMAKE_COMMAND} -E cat "-file-start
unset(RunCMake_TEST_COMMAND_WORKING_DIRECTORY)
unset(out)
+# Unset environment variables that are used for testing cmake -E
+unset(ENV{TEST_ENV})
+unset(ENV{TEST_ENV_EXPECTED})
+
run_cmake_command(E_env-no-command0 ${CMAKE_COMMAND} -E env)
run_cmake_command(E_env-no-command1 ${CMAKE_COMMAND} -E env TEST_ENV=1)
run_cmake_command(E_env-bad-arg1 ${CMAKE_COMMAND} -E env -bad-arg1)
@@ -758,6 +762,56 @@ file(COPY_FILE "${EXIT_CODE_EXE}" "${RunCMake_BINARY_DIR}/env=${exit_code}")
run_cmake_command(E_env-with-double-dash ${CMAKE_COMMAND} -E env TEST_ENV=1 -- "${RunCMake_BINARY_DIR}/env=${exit_code}" zero_exit)
run_cmake_command(E_env-without-double-dash ${CMAKE_COMMAND} -E env TEST_ENV=1 "${RunCMake_BINARY_DIR}/env=${exit_code}" zero_exit)
+## Tests of env --modify
+# Repeat the same tests as above
+run_cmake_command(E_env_modify-set ${CMAKE_COMMAND} -E env --modify TEST_ENV=set:1 ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-set.cmake)
+run_cmake_command(E_env_modify-unset ${CMAKE_COMMAND} -E env --modify TEST_ENV=set:1 ${CMAKE_COMMAND} -E env --modify TEST_ENV=unset: ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-unset.cmake)
+run_cmake_command(E_env_modify-with-double-dash ${CMAKE_COMMAND} -E env --modify TEST_ENV=set:1 -- "${RunCMake_BINARY_DIR}/env=${exit_code}" zero_exit)
+run_cmake_command(E_env_modify-without-double-dash ${CMAKE_COMMAND} -E env --modify TEST_ENV=set:1 "${RunCMake_BINARY_DIR}/env=${exit_code}" zero_exit)
+
+# Test environment modification commands
+run_cmake_command(E_env_modify-reset
+ ${CMAKE_COMMAND} -E env TEST_ENV=expected
+ ${CMAKE_COMMAND} -E env TEST_ENV_EXPECTED=expected TEST_ENV=bad_value --modify TEST_ENV=reset:
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
+
+run_cmake_command(E_env_modify-reset-to-unset
+ ${CMAKE_COMMAND} -E env --unset=TEST_ENV --unset=TEST_ENV_EXPECTED
+ ${CMAKE_COMMAND} -E env TEST_ENV=bad_value --modify TEST_ENV=reset:
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
+
+run_cmake_command(E_env_modify-string
+ ${CMAKE_COMMAND} -E env TEST_ENV_EXPECTED=expected
+ --modify TEST_ENV=unset:
+ --modify TEST_ENV=string_append:ect
+ --modify TEST_ENV=string_prepend:exp
+ --modify TEST_ENV=string_append:ed
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
+
+if (WIN32)
+ set(SEP "\\;")
+else ()
+ set(SEP ":")
+endif ()
+
+run_cmake_command(E_env_modify-path_list
+ ${CMAKE_COMMAND} -E env "TEST_ENV_EXPECTED=exp${SEP}ect${SEP}ed"
+ --modify TEST_ENV=unset:
+ --modify TEST_ENV=path_list_append:ect
+ --modify TEST_ENV=path_list_prepend:exp
+ --modify TEST_ENV=path_list_append:ed
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
+
+run_cmake_command(E_env_modify-cmake_list
+ ${CMAKE_COMMAND} -E env "TEST_ENV_EXPECTED=exp\\;ect\\;ed"
+ --modify TEST_ENV=unset:
+ --modify TEST_ENV=cmake_list_append:ect
+ --modify TEST_ENV=cmake_list_prepend:exp
+ --modify TEST_ENV=cmake_list_append:ed
+ ${CMAKE_COMMAND} -P ${RunCMake_SOURCE_DIR}/E_env-equal.cmake)
+
+run_cmake_command(E_env_modify-bad-operation ${CMAKE_COMMAND} -E env --modify TEST_ENV=unknown:)
+
run_cmake_command(E_md5sum-dir ${CMAKE_COMMAND} -E md5sum .)
run_cmake_command(E_sha1sum-dir ${CMAKE_COMMAND} -E sha1sum .)
run_cmake_command(E_sha224sum-dir ${CMAKE_COMMAND} -E sha224sum .)
@@ -941,8 +995,8 @@ set(CMAKE_DEPENDS_CHECK_C
set(CMAKE_RELATIVE_PATH_TOP_SOURCE \"${RunCMake_TEST_SOURCE_DIR}\")
set(CMAKE_RELATIVE_PATH_TOP_BINARY \"${RunCMake_TEST_BINARY_DIR}\")
")
- run_cmake_command(cmake_depends ${CMAKE_COMMAND} -E cmake_depends
- "Unix Makefiles"
+ run_cmake_command(cmake_depends ${CMAKE_COMMAND} -E env VERBOSE=1
+ ${CMAKE_COMMAND} -E cmake_depends "Unix Makefiles"
${RunCMake_TEST_SOURCE_DIR} ${RunCMake_TEST_SOURCE_DIR}
${RunCMake_TEST_BINARY_DIR} ${RunCMake_TEST_BINARY_DIR}
${RunCMake_TEST_BINARY_DIR}/CMakeFiles/DepTarget.dir/DependInfo.cmake
diff --git a/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt b/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt
index 8fe092b..cf972a8 100644
--- a/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt
+++ b/Tests/RunCMake/CommandLine/cmake_depends-stdout.txt
@@ -1 +1 @@
-^Scanning dependencies of target DepTarget$
+Scanning dependencies of target DepTarget$
diff --git a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
index 84d0479..e6a2605 100644
--- a/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
+++ b/Tests/RunCMake/CompilerLauncher/RunCMakeTest.cmake
@@ -17,7 +17,8 @@ endfunction()
function(run_compiler_launcher_env lang)
string(REGEX REPLACE "-.*" "" core_lang "${lang}")
- set(ENV{CMAKE_${core_lang}_COMPILER_LAUNCHER} "${CMAKE_COMMAND};-E;env;USED_LAUNCHER=1")
+ # Use the noop genexp $<PATH:...> genexp to validate genexp support.
+ set(ENV{CMAKE_${core_lang}_COMPILER_LAUNCHER} "$<PATH:CMAKE_PATH,${CMAKE_COMMAND}>;-E;env;USED_LAUNCHER=1")
run_compiler_launcher(${lang})
unset(ENV{CMAKE_${core_lang}_COMPILER_LAUNCHER})
endfunction()
diff --git a/Tests/RunCMake/ExternalProject/BUILD_ALWAYS-build1-stdout.txt b/Tests/RunCMake/ExternalProject/BUILD_ALWAYS-build1-stdout.txt
new file mode 100644
index 0000000..2c223f7
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BUILD_ALWAYS-build1-stdout.txt
@@ -0,0 +1,6 @@
+.*-- once: configure
+.*-- once: build
+.*-- once: install
+.*-- always: configure
+.*-- always: build
+.*-- always: install
diff --git a/Tests/RunCMake/ExternalProject/BUILD_ALWAYS-build2-stdout.txt b/Tests/RunCMake/ExternalProject/BUILD_ALWAYS-build2-stdout.txt
new file mode 100644
index 0000000..d697490
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BUILD_ALWAYS-build2-stdout.txt
@@ -0,0 +1,2 @@
+.*-- always: build
+.*-- always: install
diff --git a/Tests/RunCMake/ExternalProject/BUILD_ALWAYS.cmake b/Tests/RunCMake/ExternalProject/BUILD_ALWAYS.cmake
new file mode 100644
index 0000000..2e5fc6f
--- /dev/null
+++ b/Tests/RunCMake/ExternalProject/BUILD_ALWAYS.cmake
@@ -0,0 +1,20 @@
+include(ExternalProject)
+
+ExternalProject_Add(once
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/once-configure.cmake
+ BUILD_COMMAND "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/once-build.cmake
+ INSTALL_COMMAND "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/once-install.cmake
+ )
+
+ExternalProject_Add(always
+ DEPENDS once
+ DOWNLOAD_COMMAND ""
+ CONFIGURE_COMMAND "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/always-configure.cmake
+ BUILD_COMMAND "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/always-build.cmake
+ COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${CMAKE_CURRENT_LIST_FILE}
+ "${CMAKE_CURRENT_BINARY_DIR}/byproduct.txt"
+ BUILD_BYPRODUCTS "${CMAKE_CURRENT_BINARY_DIR}/byproduct.txt"
+ BUILD_ALWAYS 1
+ INSTALL_COMMAND "${CMAKE_COMMAND}" -P ${CMAKE_CURRENT_BINARY_DIR}/always-install.cmake
+ )
diff --git a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
index 2588d6c..f152f5b 100644
--- a/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ExternalProject/RunCMakeTest.cmake
@@ -177,6 +177,28 @@ if(doSubstitutionTest)
__ep_test_with_build(Substitutions)
endif()
+function(__ep_test_BUILD_ALWAYS)
+ set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BUILD_ALWAYS-build)
+ run_cmake(BUILD_ALWAYS)
+ set(RunCMake_TEST_NO_CLEAN 1)
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-configure.cmake" [[message(STATUS "once: configure")]])
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-build.cmake" [[message(STATUS "once: build")]])
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-install.cmake" [[message(STATUS "once: install")]])
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/always-configure.cmake" [[message(STATUS "always: configure")]])
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/always-build.cmake" [[message(STATUS "always: build")]])
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/always-install.cmake" [[message(STATUS "always: install")]])
+ run_cmake_command(BUILD_ALWAYS-build1 ${CMAKE_COMMAND} --build . --target always)
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-configure.cmake" [[message(FATAL_ERROR "once: configure should not run again")]])
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-build.cmake" [[message(FATAL_ERROR "once: build should not run again")]])
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-install.cmake" [[message(FATAL_ERROR "once: install should not run again")]])
+ if(NOT RunCMake_GENERATOR MATCHES "^(Xcode|Visual Studio 9 )")
+ # The Xcode and VS 9 build systems decide to run this every time.
+ file(WRITE "${RunCMake_TEST_BINARY_DIR}/always-configure.cmake" [[message(FATAL_ERROR "always: configure should not run again")]])
+ endif()
+ run_cmake_command(BUILD_ALWAYS-build2 ${CMAKE_COMMAND} --build . --target always)
+endfunction()
+__ep_test_BUILD_ALWAYS()
+
function(__ep_test_CONFIGURE_HANDLED_BY_BUILD)
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CONFIGURE_HANDLED_BY_BUILD-build)
run_cmake(CONFIGURE_HANDLED_BY_BUILD)
diff --git a/Tests/RunCMake/FileAPI/CMakeLists.txt b/Tests/RunCMake/FileAPI/CMakeLists.txt
index 44025d3..9a66cde 100644
--- a/Tests/RunCMake/FileAPI/CMakeLists.txt
+++ b/Tests/RunCMake/FileAPI/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 3.12)
+cmake_minimum_required(VERSION 3.13)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/FileAPI/ClientStateful-check.py b/Tests/RunCMake/FileAPI/ClientStateful-check.py
index f3d20d1..28679bb 100644
--- a/Tests/RunCMake/FileAPI/ClientStateful-check.py
+++ b/Tests/RunCMake/FileAPI/ClientStateful-check.py
@@ -108,7 +108,11 @@ def check_query_json_empty(q):
check_error_re(q, "value, object or array expected")
def check_query_json_extra(q):
- check_error_re(q, "Extra non-whitespace after JSON value")
+ if bool(os.environ.get("CMake_JSONCPP_PRE_1_7_5", "")) and is_dict(q) and sorted(q.keys()) == ["responses"]:
+ # jsoncpp < 1.7.5 did not diagnose extra non-whitespace characters
+ check_error(q["responses"], "'requests' member missing")
+ else:
+ check_error_re(q, "Extra non-whitespace after JSON value")
def check_query_not_file(q):
check_error_re(q, "failed to read from file")
diff --git a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
index 61dce17..961b73a 100644
--- a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
@@ -39,6 +39,10 @@ if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release\\;MinSizeRel\\;RelWithDebInfo")
endif()
+if(JsonCpp_VERSION_STRING AND JsonCpp_VERSION_STRING VERSION_LESS 1.7.5)
+ set(ENV{CMake_JSONCPP_PRE_1_7_5} 1)
+endif()
+
run_cmake(Nothing)
run_cmake(Empty)
run_cmake(EmptyClient)
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index d5f596e..b7623de 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -213,6 +213,16 @@ def check_directory(c):
assert is_int(at["index"])
assert c["targets"][at["index"]]["name"] == et["index"]
+ if e.get("cxxModuleBmiTarget", None) is not None:
+ expected_keys.append("cxxModuleBmiTarget")
+ et = e["cxxModuleBmiTarget"]
+ at = a["cxxModuleBmiTarget"]
+ assert is_dict(at)
+ assert sorted(at.keys()) == ["id", "index"]
+ assert matches(at["id"], et["id"])
+ assert is_int(at["index"])
+ assert c["targets"][at["index"]]["name"] == et["index"]
+
if e["backtrace"] is not None:
expected_keys.append("backtrace")
check_backtrace(d, a["backtrace"], e["backtrace"])
@@ -654,6 +664,7 @@ def gen_check_directories(c, g):
read_codemodel_json_data("directories/dir_dir.json"),
read_codemodel_json_data("directories/external.json"),
read_codemodel_json_data("directories/fileset.json"),
+ read_codemodel_json_data("directories/subdir.json"),
]
if matches(g["name"], "^Visual Studio "):
@@ -712,6 +723,7 @@ def gen_check_targets(c, g, inSource):
read_codemodel_json_data("targets/c_shared_exe.json"),
read_codemodel_json_data("targets/c_static_lib.json"),
read_codemodel_json_data("targets/c_static_exe.json"),
+ read_codemodel_json_data("targets/c_subdir.json"),
read_codemodel_json_data("targets/all_build_cxx.json"),
read_codemodel_json_data("targets/zero_check_cxx.json"),
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json
index 6514910..de8b177 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/alias.json
@@ -10,7 +10,7 @@
"^cxx_alias_exe::@53632cba2752272bb008$"
],
"projectName": "Alias",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": null,
"installers": []
}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json
index c89e4f9..e57191c 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/custom.json
@@ -10,7 +10,7 @@
"^custom_tgt::@c11385ffed57b860da63$"
],
"projectName": "Custom",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": null,
"installers": []
}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
index 8052c1a..28f2b99 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/cxx.json
@@ -16,7 +16,7 @@
"^cxx_static_lib::@a56b12a3f5c0529fb296$"
],
"projectName": "Cxx",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": true,
"installers": [
{
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json
index 8509f08..2a3756e 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir.json
@@ -7,7 +7,7 @@
],
"targetIds": null,
"projectName": "codemodel-v2",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": null,
"installers": []
}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json
index 27184cd..12677f2 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/dir_dir.json
@@ -5,7 +5,7 @@
"childSources": null,
"targetIds": null,
"projectName": "codemodel-v2",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": null,
"installers": []
}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json
index 6d2952d..f1199c3 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/external.json
@@ -9,7 +9,7 @@
"^generated_exe::@[0-9a-f]+$"
],
"projectName": "External",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": true,
"installers": [
{
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/fileset.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/fileset.json
index 4774a13..c4df2ec 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/fileset.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/fileset.json
@@ -8,7 +8,7 @@
"^c_headers_2::@6b8db101d64c125f29fe$"
],
"projectName": "codemodel-v2",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": true,
"installers": [
{
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json
index 92b9526..8210d7f 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/imported.json
@@ -13,7 +13,7 @@
"^link_imported_static_exe::@ba7eb709d0b48779c6c8$"
],
"projectName": "Imported",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": true,
"installers": [
{
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
index 90664dc..08edd64 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/interface.json
@@ -9,7 +9,7 @@
"^iface_srcs::@25b7fa8ea00134654b85$"
],
"projectName": "Interface",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": null,
"installers": []
}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/subdir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/subdir.json
new file mode 100644
index 0000000..996da47
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/subdir.json
@@ -0,0 +1,11 @@
+{
+ "source": "^subdir$",
+ "build": "^subdir$",
+ "parentSource": "^\\.$",
+ "childSources": null,
+ "targetIds": null,
+ "projectName": "codemodel-v2",
+ "minimumCMakeVersion": "3.13",
+ "hasInstallRule": null,
+ "installers": []
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
index e7b146f..aed07e2 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/directories/top.json
@@ -11,7 +11,8 @@
"^object$",
"^.*/Tests/RunCMake/FileAPIExternalSource$",
"^dir$",
- "^fileset$"
+ "^fileset$",
+ "^subdir$"
],
"targetIds": [
"^ALL_BUILD::@6890427a1f51a3e7e1df$",
@@ -22,10 +23,11 @@
"^c_shared_lib::@6890427a1f51a3e7e1df$",
"^c_static_exe::@6890427a1f51a3e7e1df$",
"^c_static_lib::@6890427a1f51a3e7e1df$",
+ "^c_subdir::@6890427a1f51a3e7e1df$",
"^interface_exe::@6890427a1f51a3e7e1df$"
],
"projectName": "codemodel-v2",
- "minimumCMakeVersion": "3.12",
+ "minimumCMakeVersion": "3.13",
"hasInstallRule": true,
"installers": [
{
@@ -48,7 +50,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 39,
+ "line": 42,
"command": "install",
"hasParent": true
},
@@ -93,7 +95,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 42,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -141,7 +143,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 42,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -186,7 +188,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 42,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -230,7 +232,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 42,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -274,7 +276,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 47,
+ "line": 50,
"command": "install",
"hasParent": true
},
@@ -321,7 +323,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 49,
+ "line": 52,
"command": "install",
"hasParent": true
},
@@ -366,7 +368,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 50,
+ "line": 53,
"command": "install",
"hasParent": true
},
@@ -415,7 +417,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 51,
+ "line": 54,
"command": "install",
"hasParent": true
},
@@ -467,7 +469,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 52,
+ "line": 55,
"command": "install",
"hasParent": true
},
@@ -516,7 +518,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 53,
+ "line": 56,
"command": "install",
"hasParent": true
},
@@ -558,7 +560,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 54,
+ "line": 57,
"command": "install",
"hasParent": true
},
@@ -600,7 +602,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 55,
+ "line": 58,
"command": "install",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
index 0d6c4a1..151c0a8 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/projects/codemodel-v2.json
@@ -14,7 +14,8 @@
"^\\.$",
"^dir$",
"^dir/dir$",
- "^fileset$"
+ "^fileset$",
+ "^subdir$"
],
"targetIds": [
"^ALL_BUILD::@6890427a1f51a3e7e1df$",
@@ -26,6 +27,7 @@
"^c_shared_exe::@6890427a1f51a3e7e1df$",
"^c_static_lib::@6890427a1f51a3e7e1df$",
"^c_static_exe::@6890427a1f51a3e7e1df$",
+ "^c_subdir::@6890427a1f51a3e7e1df$",
"^c_headers_1::@6b8db101d64c125f29fe$",
"^c_headers_2::@6b8db101d64c125f29fe$"
]
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
index 4e772a7..0d45d07 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/all_build_top.json
@@ -96,6 +96,10 @@
"backtrace": null
},
{
+ "id": "^c_subdir::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ },
+ {
"id": "^c_static_exe::@6890427a1f51a3e7e1df$",
"backtrace": null
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
index b4318dd..9a210ff 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_shared_lib.json
@@ -115,7 +115,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 42,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -145,7 +145,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 42,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -175,7 +175,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 47,
+ "line": 50,
"command": "install",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
new file mode 100644
index 0000000..12ec917
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/c_subdir.json
@@ -0,0 +1,150 @@
+{
+ "name": "c_subdir",
+ "id": "^c_subdir::@6890427a1f51a3e7e1df$",
+ "directorySource": "^\\.$",
+ "projectName": "codemodel-v2",
+ "type": "STATIC_LIBRARY",
+ "isGeneratorProvided": null,
+ "sources": [
+ {
+ "path": "^subdir/empty\\.c$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "C",
+ "backtrace": [
+ {
+ "file": "^subdir/CMakeLists\\.txt$",
+ "line": 4,
+ "command": "target_sources",
+ "hasParent": true
+ },
+ {
+ "file": "^subdir/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ "^subdir/empty\\.c$"
+ ]
+ }
+ ],
+ "compileGroups": [
+ {
+ "language": "C",
+ "sourcePaths": [
+ "^subdir/empty\\.c$"
+ ],
+ "includes": [
+ {
+ "path": "^.*/Tests/RunCMake/FileAPI/subdir$",
+ "isSystem": null,
+ "backtrace": [
+ {
+ "file": "^subdir/CMakeLists\\.txt$",
+ "line": 2,
+ "command": "target_include_directories",
+ "hasParent": true
+ },
+ {
+ "file": "^subdir/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "defines": [
+ {
+ "define": "SUBDIR",
+ "backtrace": [
+ {
+ "file": "^subdir/CMakeLists\\.txt$",
+ "line": 1,
+ "command": "target_compile_definitions",
+ "hasParent": true
+ },
+ {
+ "file": "^subdir/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": null
+ }
+ ],
+ "backtrace": [
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": 17,
+ "command": "add_library",
+ "hasParent": true
+ },
+ {
+ "file": "^codemodel-v2\\.cmake$",
+ "line": null,
+ "command": null,
+ "hasParent": true
+ },
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": 3,
+ "command": "include",
+ "hasParent": true
+ },
+ {
+ "file": "^CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ],
+ "folder": null,
+ "nameOnDisk": "^(lib)?c_subdir\\.(a|lib)$",
+ "artifacts": [
+ {
+ "path": "^((Debug|Release|RelWithDebInfo|MinSizeRel)/)?(lib)?c_subdir\\.(a|lib)$",
+ "_dllExtra": false
+ }
+ ],
+ "build": "^\\.$",
+ "source": "^\\.$",
+ "install": null,
+ "link": null,
+ "archive": {
+ "lto": null
+ },
+ "dependencies": [
+ {
+ "id": "^c_lib::@6890427a1f51a3e7e1df$",
+ "backtrace": [
+ {
+ "file": "^subdir/CMakeLists\\.txt$",
+ "line": 3,
+ "command": "target_link_libraries",
+ "hasParent": true
+ },
+ {
+ "file": "^subdir/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "id": "^ZERO_CHECK::@6890427a1f51a3e7e1df$",
+ "backtrace": null
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
index 5769f0c..16d074a 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
@@ -136,7 +136,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 39,
+ "line": 42,
"command": "install",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
index 1fe4d67..03f4cb9 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_shared_lib.json
@@ -91,7 +91,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 42,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -121,7 +121,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 42,
+ "line": 45,
"command": "install",
"hasParent": true
},
@@ -151,7 +151,7 @@
"backtrace": [
{
"file": "^codemodel-v2\\.cmake$",
- "line": 47,
+ "line": 50,
"command": "install",
"hasParent": true
},
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2.cmake b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
index 019eb87..09db216 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2.cmake
+++ b/Tests/RunCMake/FileAPI/codemodel-v2.cmake
@@ -14,6 +14,9 @@ add_library(c_static_lib STATIC empty.c)
add_executable(c_static_exe empty.c)
target_link_libraries(c_static_exe PRIVATE c_static_lib)
+add_library(c_subdir STATIC)
+add_subdirectory(subdir)
+
add_subdirectory(cxx)
add_subdirectory(alias)
add_subdirectory(object)
diff --git a/Tests/RunCMake/FileAPI/subdir/CMakeLists.txt b/Tests/RunCMake/FileAPI/subdir/CMakeLists.txt
new file mode 100644
index 0000000..b8f4550
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/subdir/CMakeLists.txt
@@ -0,0 +1,4 @@
+target_compile_definitions(c_subdir PRIVATE SUBDIR)
+target_include_directories(c_subdir PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries(c_subdir PRIVATE c_lib)
+target_sources(c_subdir PRIVATE empty.c)
diff --git a/Tests/RunCMake/FileAPI/subdir/empty.c b/Tests/RunCMake/FileAPI/subdir/empty.c
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/subdir/empty.c
diff --git a/Tests/RunCMake/File_Archive/RunCMakeTest.cmake b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
index 3908f42..dad0dd3 100644
--- a/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Archive/RunCMakeTest.cmake
@@ -13,6 +13,9 @@ run_cmake(zip)
# Extracting only selected files or directories
run_cmake(zip-filtered)
+run_cmake(create-missing-args)
+run_cmake(extract-missing-args)
+
run_cmake(unsupported-format)
run_cmake(zip-with-bad-compression)
run_cmake(7zip-with-bad-compression)
diff --git a/Tests/RunCMake/File_Archive/create-missing-args-result.txt b/Tests/RunCMake/File_Archive/create-missing-args-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/create-missing-args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Archive/create-missing-args-stderr.txt b/Tests/RunCMake/File_Archive/create-missing-args-stderr.txt
new file mode 100644
index 0000000..fd026f9
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/create-missing-args-stderr.txt
@@ -0,0 +1,19 @@
+^CMake Error at create-missing-args.cmake:[0-9]+ \(file\):
+ Error after keyword "COMPRESSION":
+
+ missing required value
+
+ Error after keyword "COMPRESSION_LEVEL":
+
+ missing required value
+
+ Error after keyword "FORMAT":
+
+ missing required value
+
+ Error after keyword "OUTPUT":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/File_Archive/create-missing-args.cmake b/Tests/RunCMake/File_Archive/create-missing-args.cmake
new file mode 100644
index 0000000..a0c84d2
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/create-missing-args.cmake
@@ -0,0 +1,8 @@
+file(ARCHIVE_CREATE
+ OUTPUT # missing output path
+ FORMAT # missing output format
+ COMPRESSION # missing compression type
+ COMPRESSION_LEVEL # missing compression level
+ MTIME # missing modification time
+ PATHS # no paths
+ )
diff --git a/Tests/RunCMake/File_Archive/extract-missing-args-result.txt b/Tests/RunCMake/File_Archive/extract-missing-args-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/extract-missing-args-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Archive/extract-missing-args-stderr.txt b/Tests/RunCMake/File_Archive/extract-missing-args-stderr.txt
new file mode 100644
index 0000000..0c93ece
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/extract-missing-args-stderr.txt
@@ -0,0 +1,11 @@
+^CMake Error at extract-missing-args.cmake:[0-9]+ \(file\):
+ Error after keyword "DESTINATION":
+
+ missing required value
+
+ Error after keyword "INPUT":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/File_Archive/extract-missing-args.cmake b/Tests/RunCMake/File_Archive/extract-missing-args.cmake
new file mode 100644
index 0000000..21c5d99
--- /dev/null
+++ b/Tests/RunCMake/File_Archive/extract-missing-args.cmake
@@ -0,0 +1,5 @@
+file(ARCHIVE_EXTRACT
+ INPUT # missing input
+ DESTINATION # missing destination
+ PATTERNS # no patterns
+ )
diff --git a/Tests/RunCMake/File_Configure/BadArgContent-stderr.txt b/Tests/RunCMake/File_Configure/BadArgContent-stderr.txt
index a6ea314..72292f9 100644
--- a/Tests/RunCMake/File_Configure/BadArgContent-stderr.txt
+++ b/Tests/RunCMake/File_Configure/BadArgContent-stderr.txt
@@ -1,4 +1,7 @@
CMake Error at BadArgContent.cmake:[0-9]+ \(file\):
- file CONFIGURE CONTENT option needs a value.
+ Error after keyword "CONTENT":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt b/Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt
index b5a924c..d793f48 100644
--- a/Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt
+++ b/Tests/RunCMake/File_Configure/BadArgOutput-stderr.txt
@@ -1,4 +1,7 @@
CMake Error at BadArgOutput.cmake:[0-9]+ \(file\):
- file CONFIGURE OUTPUT option needs a value.
+ Error after keyword "OUTPUT":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/File_Configure/NoArgContent-result.txt b/Tests/RunCMake/File_Configure/NoArgContent-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NoArgContent-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Configure/NoArgContent-stderr.txt b/Tests/RunCMake/File_Configure/NoArgContent-stderr.txt
new file mode 100644
index 0000000..2e8dd9a
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NoArgContent-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoArgContent.cmake:[0-9]+ \(file\):
+ file CONFIGURE CONTENT option is mandatory.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/File_Configure/NoArgContent.cmake b/Tests/RunCMake/File_Configure/NoArgContent.cmake
new file mode 100644
index 0000000..cf52c46
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NoArgContent.cmake
@@ -0,0 +1 @@
+file(CONFIGURE OUTPUT "")
diff --git a/Tests/RunCMake/File_Configure/NoArgOutput-result.txt b/Tests/RunCMake/File_Configure/NoArgOutput-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NoArgOutput-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/File_Configure/NoArgOutput-stderr.txt b/Tests/RunCMake/File_Configure/NoArgOutput-stderr.txt
new file mode 100644
index 0000000..53de48b
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NoArgOutput-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at NoArgOutput.cmake:[0-9]+ \(file\):
+ file CONFIGURE OUTPUT option is mandatory.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/File_Configure/NoArgOutput.cmake b/Tests/RunCMake/File_Configure/NoArgOutput.cmake
new file mode 100644
index 0000000..77e9cdc
--- /dev/null
+++ b/Tests/RunCMake/File_Configure/NoArgOutput.cmake
@@ -0,0 +1 @@
+file(CONFIGURE CONTENT "")
diff --git a/Tests/RunCMake/File_Configure/RunCMakeTest.cmake b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
index 5022985..008ce67 100644
--- a/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Configure/RunCMakeTest.cmake
@@ -9,6 +9,8 @@ run_cmake(DirOutput)
run_cmake(NewLineStyle-NoArg)
run_cmake(NewLineStyle-ValidArg)
run_cmake(NewLineStyle-WrongArg)
+run_cmake(NoArgOutput)
+run_cmake(NoArgContent)
run_cmake(SubDir)
run_cmake(AtOnly)
run_cmake(EscapeQuotes)
diff --git a/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt b/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt
index e823b25..708e6be 100644
--- a/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt
+++ b/Tests/RunCMake/File_Generate/EmptyCondition1-stderr.txt
@@ -1,4 +1,7 @@
CMake Error at EmptyCondition1.cmake:2 \(file\):
- file Incorrect arguments to GENERATE subcommand.
+ Error after keyword "CONDITION":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/InputAndContent-check.cmake b/Tests/RunCMake/File_Generate/InputAndContent-check.cmake
new file mode 100644
index 0000000..5c9b803
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/InputAndContent-check.cmake
@@ -0,0 +1,8 @@
+file(READ "${RunCMake_TEST_BINARY_DIR}/output-INPUT.txt" input)
+if(NOT input MATCHES "INPUT file")
+ string(APPEND RunCMake_TEST_FAILED "INPUT incorrectly overridden by CONTENT")
+endif()
+file(READ "${RunCMake_TEST_BINARY_DIR}/output-CONTENT.txt" content)
+if(NOT content MATCHES "CONTENT argument")
+ string(APPEND RunCMake_TEST_FAILED "CONTENT incorrectly overridden by INPUT")
+endif()
diff --git a/Tests/RunCMake/File_Generate/InputAndContent-input.txt b/Tests/RunCMake/File_Generate/InputAndContent-input.txt
new file mode 100644
index 0000000..73f162b
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/InputAndContent-input.txt
@@ -0,0 +1 @@
+INPUT file
diff --git a/Tests/RunCMake/File_Generate/InputAndContent.cmake b/Tests/RunCMake/File_Generate/InputAndContent.cmake
new file mode 100644
index 0000000..9c3977a
--- /dev/null
+++ b/Tests/RunCMake/File_Generate/InputAndContent.cmake
@@ -0,0 +1,10 @@
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-INPUT.txt"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/InputAndContent-input.txt"
+ CONTENT "CONTENT argument"
+)
+file(GENERATE
+ OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/output-CONTENT.txt"
+ CONTENT "CONTENT argument"
+ INPUT "${CMAKE_CURRENT_SOURCE_DIR}/InputAndContent-input.txt"
+)
diff --git a/Tests/RunCMake/File_Generate/NewLineStyle-NoArg-stderr.txt b/Tests/RunCMake/File_Generate/NewLineStyle-NoArg-stderr.txt
index bc71f2f..b1b7f80 100644
--- a/Tests/RunCMake/File_Generate/NewLineStyle-NoArg-stderr.txt
+++ b/Tests/RunCMake/File_Generate/NewLineStyle-NoArg-stderr.txt
@@ -1,4 +1,7 @@
CMake Error at NewLineStyle-NoArg.cmake:[0-9]+ \(file\):
- file Incorrect arguments to GENERATE subcommand.
+ Error after keyword "NEWLINE_STYLE":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
index be3bf04..5a670ae 100644
--- a/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
+++ b/Tests/RunCMake/File_Generate/RunCMakeTest.cmake
@@ -17,6 +17,7 @@ run_cmake(EmptyCondition2)
run_cmake(BadCondition)
run_cmake(DebugEvaluate)
run_cmake(GenerateSource)
+run_cmake(InputAndContent)
run_cmake(OutputNameMatchesSources)
run_cmake(OutputNameMatchesObjects)
run_cmake(OutputNameMatchesOtherSources)
diff --git a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
index f479dcf..661ae3f 100644
--- a/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FindPkgConfig/RunCMakeTest.cmake
@@ -24,6 +24,27 @@ endif()
# We need a real pkg-config to run the test for get_variable.
find_package(PkgConfig)
if (PKG_CONFIG_FOUND)
+ string(FIND "${CMAKE_CURRENT_BINARY_DIR}" " " IS_SPACES_IN_PATH)
+ if(IS_SPACES_IN_PATH GREATER -1)
+ string(REPLACE " " "\\ " ESCAPED_ROOT "${CMAKE_CURRENT_BINARY_DIR}")
+ file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test_spaces.pc" "
+libdir=${ESCAPED_ROOT}
+Name: test_spaces.pc
+Version: 0.0
+Description: test spaces
+Libs: -L\${libdir}
+")
+ set(PKG_CONFIG_PATH_SAVED "$ENV{PKG_CONFIG_PATH}")
+ set(ENV{PKG_CONFIG_PATH} "${CMAKE_CURRENT_BINARY_DIR}")
+ execute_process(COMMAND "${PKG_CONFIG_EXECUTABLE}" --libs test_spaces
+ ERROR_QUIET COMMAND_ERROR_IS_FATAL ANY
+ OUTPUT_VARIABLE test_spaces_LIBS)
+ set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH_SAVED}")
+ string(STRIP "${test_spaces_LIBS}" test_spaces_LIBS_STRIPPED)
+ if(NOT "${test_spaces_LIBS_STRIPPED}" STREQUAL "-L${ESCAPED_ROOT}")
+ set(PKG_CONFIG_DONT_SUPPORT_SPACES_IN_PATH TRUE)
+ endif()
+ endif()
run_cmake(FindPkgConfig_GET_VARIABLE)
run_cmake(FindPkgConfig_GET_VARIABLE_PREFIX_PATH)
run_cmake(FindPkgConfig_GET_VARIABLE_PKGCONFIG_PATH)
@@ -32,5 +53,7 @@ if (PKG_CONFIG_FOUND)
run_cmake(FindPkgConfig_VERSION_OPERATORS)
run_cmake(FindPkgConfig_GET_MATCHING_MODULE_NAME)
run_cmake(FindPkgConfig_empty_target)
- run_cmake(FindPkgConfig_LIBRARY_PATH)
+ if(NOT PKG_CONFIG_DONT_SUPPORT_SPACES_IN_PATH)
+ run_cmake(FindPkgConfig_LIBRARY_PATH)
+ endif()
endif ()
diff --git a/Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake b/Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake
new file mode 100644
index 0000000..a1ae6ac
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CompileCommands-check.cmake
@@ -0,0 +1,28 @@
+set(expected_compile_commands
+[==[^\[
+{
+ "directory": "[^
+]*(/Tests/RunCMake/NinjaMultiConfig/CompileCommands-build|\\\\Tests\\\\RunCMake\\\\NinjaMultiConfig\\\\CompileCommands-build)",
+ "command": "[^
+]*Debug[^
+]*",
+ "file": "[^
+]*(/Tests/RunCMake/NinjaMultiConfig/main\.c|\\\\Tests\\\\RunCMake\\\\NinjaMultiConfig\\\\main\.c)"
+},
+{
+ "directory": "[^
+]*(/Tests/RunCMake/NinjaMultiConfig/CompileCommands-build|\\\\Tests\\\\RunCMake\\\\NinjaMultiConfig\\\\CompileCommands-build)",
+ "command": "[^
+]*Release[^
+]*",
+ "file": "[^
+]*(/Tests/RunCMake/NinjaMultiConfig/main\.c|\\\\Tests\\\\RunCMake\\\\NinjaMultiConfig\\\\main\.c)"
+}
+]$]==])
+
+file(READ "${RunCMake_TEST_BINARY_DIR}/compile_commands.json" actual_compile_commands)
+if(NOT actual_compile_commands MATCHES "${expected_compile_commands}")
+ string(REPLACE "\n" "\n " expected_compile_commands_formatted "${expected_compile_commands}")
+ string(REPLACE "\n" "\n " actual_compile_commands_formatted "${actual_compile_commands}")
+ string(APPEND RunCMake_TEST_FAILED "Expected compile_commands.json to match:\n ${expected_compile_commands_formatted}\nActual compile_commands.json:\n ${actual_compile_commands_formatted}\n")
+endif()
diff --git a/Tests/RunCMake/NinjaMultiConfig/CompileCommands.cmake b/Tests/RunCMake/NinjaMultiConfig/CompileCommands.cmake
new file mode 100644
index 0000000..fc44d5a
--- /dev/null
+++ b/Tests/RunCMake/NinjaMultiConfig/CompileCommands.cmake
@@ -0,0 +1,3 @@
+enable_language(C)
+
+add_executable(exe main.c)
diff --git a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
index 738bc6c..c040e8f 100644
--- a/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
+++ b/Tests/RunCMake/NinjaMultiConfig/RunCMakeTest.cmake
@@ -453,6 +453,11 @@ run_cmake_command(NoUnusedVariables ${CMAKE_COMMAND} ${CMAKE_CURRENT_LIST_DIR}
"-DCMAKE_DEFAULT_BUILD_TYPE=Debug"
"-DCMAKE_DEFAULT_CONFIGS=all"
)
+unset(RunCMake_TEST_BINARY_DIR)
+
+set(RunCMake_TEST_OPTIONS "-DCMAKE_CONFIGURATION_TYPES=Debug\\;Release;-DCMAKE_CROSS_CONFIGS=all;-DCMAKE_EXPORT_COMPILE_COMMANDS=ON")
+run_cmake(CompileCommands)
+unset(RunCMake_TEST_OPTIONS)
# CudaSimple uses separable compilation, which is currently only supported on NVCC.
if(CMake_TEST_CUDA)
diff --git a/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake b/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake
index 51c8832..691c495 100644
--- a/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake
+++ b/Tests/RunCMake/ParseImplicitLinkInfo/ParseImplicitLinkInfo.cmake
@@ -154,6 +154,7 @@ foreach(t ${targets})
cmake_parse_implicit_link_info("${input}" implicit_libs idirs implicit_fwks log
"${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}"
+ LANGUAGE ${lang}
COMPUTE_IMPLICIT_OBJECTS implicit_objs)
set(library_arch)
diff --git a/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake b/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
index bcdc101..1701a36 100644
--- a/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
+++ b/Tests/RunCMake/VS10Project/InterfaceLibSources-check.cmake
@@ -5,6 +5,7 @@ if(NOT EXISTS "${vcProjectFile}")
endif()
set(found_iface_h 0)
+set(found_int_dir 0)
file(STRINGS "${vcProjectFile}" lines)
foreach(line IN LISTS lines)
if(line MATCHES "<([A-Za-z0-9_]+) +Include=.*iface\\.h")
@@ -19,7 +20,15 @@ foreach(line IN LISTS lines)
endif()
set(found_iface_h 1)
endif()
+ if(line MATCHES "^ *<IntDir [^<>]+>[^<>]+</IntDir>")
+ set(found_int_dir 1)
+ endif()
endforeach()
if(NOT found_iface_h)
set(RunCMake_TEST_FAILED "iface.h not referenced in\n ${vcProjectFile}")
+ return()
+endif()
+if(NOT found_int_dir)
+ set(RunCMake_TEST_FAILED "No references to IntDir in\n ${vcProjectFile}")
+ return()
endif()
diff --git a/Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake b/Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake
index 9c9074e..22e2bb3 100644
--- a/Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VsDotnetSdk/RunCMakeTest.cmake
@@ -4,6 +4,7 @@ include(RunCMake)
run_cmake(VsDotnetSdkCustomCommandsTarget)
run_cmake(VsDotnetSdkCustomCommandsSource)
run_cmake(VsDotnetSdkStartupObject)
+run_cmake(VsDotnetSdkDefines)
run_cmake(DotnetSdkVariables)
function(run_VsDotnetSdk)
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkDefines-check.cmake b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkDefines-check.cmake
new file mode 100644
index 0000000..eaeba24
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkDefines-check.cmake
@@ -0,0 +1,64 @@
+#
+# Check C# VS project for required elements.
+#
+set(csProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.csproj")
+if(NOT EXISTS "${csProjectFile}")
+ set(RunCMake_TEST_FAILED "Project file ${csProjectFile} does not exist.")
+ return()
+endif()
+
+
+set(inDebug FALSE)
+set(inRelease FALSE)
+set(debugOK FALSE)
+set(releaseOK FALSE)
+
+
+file(STRINGS "${csProjectFile}" lines)
+foreach(line IN LISTS lines)
+ #message(STATUS ${line})
+ if(line MATCHES "^ *<PropertyGroup .*Debug.*")
+ set(inDebug TRUE)
+ elseif(line MATCHES "^ *<PropertyGroup .*Release.*")
+ set(inRelease TRUE)
+ elseif(line MATCHES "^ *</PropertyGroup> *$")
+ set(inRelease FALSE)
+ set(inDebug FALSE)
+ elseif(inDebug AND
+ (line MATCHES "^ *<DefineConstants>.*MY_FOO_DEFINE.*</DefineConstants> *$") AND
+ (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_DEBUG.*</DefineConstants> *$") AND
+ (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_RELEASE.*</DefineConstants> *$")) AND
+ (NOT (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$"))
+ )
+ set(debugOK TRUE)
+ elseif(inRelease AND
+ (line MATCHES "^ *<DefineConstants>.*MY_FOO_DEFINE.*</DefineConstants> *$") AND
+ (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_RELEASE.*</DefineConstants> *$") AND
+ (NOT (line MATCHES "^ *<DefineConstants>.*DEFINE_ONLY_FOR_DEBUG.*</DefineConstants> *$")) AND
+ (NOT (line MATCHES "^ *<DefineConstants>.*MY_BAR_ASSIGNMENT=bar.*</DefineConstants> *$"))
+ )
+ set(releaseOK TRUE)
+ endif()
+endforeach()
+
+function(print_csprojfile)
+ file(STRINGS "${csProjectFile}" lines)
+ foreach(line IN LISTS lines)
+ message(STATUS ${line})
+ endforeach()
+endfunction()
+
+
+if(NOT debugOK)
+ message(STATUS "Failed to set Debug configuration defines correctly.")
+ set(RunCMake_TEST_FAILED "Failed to set Debug configuration defines correctly.")
+ print_csprojfile()
+ return()
+endif()
+
+if(NOT releaseOK)
+ message(STATUS "Failed to set Release configuration defines correctly.")
+ set(RunCMake_TEST_FAILED "Failed to set Release configuration defines correctly.")
+ print_csprojfile()
+ return()
+endif()
diff --git a/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkDefines.cmake b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkDefines.cmake
new file mode 100644
index 0000000..d89f19b
--- /dev/null
+++ b/Tests/RunCMake/VsDotnetSdk/VsDotnetSdkDefines.cmake
@@ -0,0 +1,19 @@
+enable_language(CSharp)
+if(NOT CMAKE_CSharp_COMPILER)
+ return()
+endif()
+
+set(CMAKE_DOTNET_SDK "Microsoft.NET.Sdk")
+set(CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION "net5.0")
+
+add_executable(foo csharponly.cs lib1.cs)
+
+# Issue 23376
+target_compile_definitions(
+ foo
+ PUBLIC
+ MY_FOO_DEFINE
+ "MY_BAR_ASSIGNMENT=bar"
+ $<$<CONFIG:Debug>:DEFINE_ONLY_FOR_DEBUG>
+ $<$<CONFIG:Release>:DEFINE_ONLY_FOR_RELEASE>
+)
diff --git a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
index be44ecd..6bad527 100644
--- a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty-check.cmake
@@ -29,6 +29,8 @@ check_property("UNDEFINED_BEHAVIOUR_SANITIZER" "enableUBSanitizer")
check_property("UNDEFINED_BEHAVIOUR_SANITIZER_STOP" "stopOnEveryUBSanitizerIssue")
check_property("DISABLE_MAIN_THREAD_CHECKER" "disableMainThreadChecker")
check_property("MAIN_THREAD_CHECKER_STOP" "stopOnEveryMainThreadCheckerIssue")
+check_property("DISABLE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION" "enableGPUValidationMode")
+check_property("ENABLE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION" "enableGPUShaderValidationMode")
check_property("MALLOC_SCRIBBLE" "MallocScribble")
check_property("MALLOC_GUARD_EDGES" "MallocGuardEdges")
@@ -43,6 +45,8 @@ check_property("ENABLE_GPU_FRAME_CAPTURE_MODE_DISABLED" "enableGPUFrameCaptureMo
check_property("ENABLE_GPU_FRAME_CAPTURE_MODE_METAL" "enableGPUFrameCaptureMode=\"1\"")
check_property("ENABLE_GPU_FRAME_CAPTURE_MODE_DISABLED_MIXED_CASE" "enableGPUFrameCaptureMode=\"3\"")
check_property("ENABLE_GPU_FRAME_CAPTURE_MODE_METAL_MIXED_CASE" "enableGPUFrameCaptureMode=\"1\"")
+check_property("LAUNCH_MODE_AUTO" "launchStyle=\"0\"")
+check_property("LAUNCH_MODE_WAIT" "launchStyle=\"1\"")
check_property("EXECUTABLE" "myExecutable")
check_property("ARGUMENTS" [=["--foo"]=])
diff --git a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
index 126a9fc..267e379 100644
--- a/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
+++ b/Tests/RunCMake/XcodeProject/XcodeSchemaProperty.cmake
@@ -32,12 +32,16 @@ function(create_scheme_for_property scheme property value)
set_target_properties(${scheme} PROPERTIES XCODE_SCHEME_${property} "${value}")
endfunction()
+create_scheme_for_property(DISABLE_XCODE_SCHEME_ENABLE_GPU_API_VALIDATION ENABLE_GPU_API_VALIDATION OFF)
+create_scheme_for_property(ENABLE_XCODE_SCHEME_ENABLE_GPU_SHADER_VALIDATION ENABLE_GPU_SHADER_VALIDATION ON)
create_scheme_for_property(ENABLE_GPU_FRAME_CAPTURE_MODE_1 ENABLE_GPU_FRAME_CAPTURE_MODE 1)
create_scheme_for_property(ENABLE_GPU_FRAME_CAPTURE_MODE_3 ENABLE_GPU_FRAME_CAPTURE_MODE 3)
create_scheme_for_property(ENABLE_GPU_FRAME_CAPTURE_MODE_DISABLED ENABLE_GPU_FRAME_CAPTURE_MODE Disabled)
create_scheme_for_property(ENABLE_GPU_FRAME_CAPTURE_MODE_METAL ENABLE_GPU_FRAME_CAPTURE_MODE Metal)
create_scheme_for_property(ENABLE_GPU_FRAME_CAPTURE_MODE_DISABLED_MIXED_CASE ENABLE_GPU_FRAME_CAPTURE_MODE DISAbled)
create_scheme_for_property(ENABLE_GPU_FRAME_CAPTURE_MODE_METAL_MIXED_CASE ENABLE_GPU_FRAME_CAPTURE_MODE METal)
+create_scheme_for_property(LAUNCH_MODE_AUTO LAUNCH_MODE AUTO)
+create_scheme_for_property(LAUNCH_MODE_WAIT LAUNCH_MODE WAIT)
create_scheme_for_property(EXECUTABLE EXECUTABLE myExecutable)
create_scheme_for_property(ARGUMENTS ARGUMENTS "--foo;--bar=baz")
create_scheme_for_property(ENVIRONMENT ENVIRONMENT "FOO=foo;BAR=bar")
diff --git a/Tests/RunCMake/block/CMakeLists.txt b/Tests/RunCMake/block/CMakeLists.txt
new file mode 100644
index 0000000..45cd10e
--- /dev/null
+++ b/Tests/RunCMake/block/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.3...3.25)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/block/EndAlone-result.txt b/Tests/RunCMake/block/EndAlone-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/EndAlone-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/EndAlone-stderr.txt b/Tests/RunCMake/block/EndAlone-stderr.txt
new file mode 100644
index 0000000..a588dd7
--- /dev/null
+++ b/Tests/RunCMake/block/EndAlone-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at EndAlone.cmake:[0-9]+ \(endblock\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/EndAlone.cmake b/Tests/RunCMake/block/EndAlone.cmake
new file mode 100644
index 0000000..0c428a9
--- /dev/null
+++ b/Tests/RunCMake/block/EndAlone.cmake
@@ -0,0 +1 @@
+endblock()
diff --git a/Tests/RunCMake/block/EndAloneWithArgument-result.txt b/Tests/RunCMake/block/EndAloneWithArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/EndAloneWithArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/EndAloneWithArgument-stderr.txt b/Tests/RunCMake/block/EndAloneWithArgument-stderr.txt
new file mode 100644
index 0000000..c3d25a3
--- /dev/null
+++ b/Tests/RunCMake/block/EndAloneWithArgument-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at EndAloneWithArgument.cmake:[0-9]+ \(endblock\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/EndAloneWithArgument.cmake b/Tests/RunCMake/block/EndAloneWithArgument.cmake
new file mode 100644
index 0000000..05df5b0
--- /dev/null
+++ b/Tests/RunCMake/block/EndAloneWithArgument.cmake
@@ -0,0 +1 @@
+endblock(WRONG_ARG)
diff --git a/Tests/RunCMake/block/EndMissing-result.txt b/Tests/RunCMake/block/EndMissing-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/EndMissing-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/EndMissing-stderr.txt b/Tests/RunCMake/block/EndMissing-stderr.txt
new file mode 100644
index 0000000..b9739a5
--- /dev/null
+++ b/Tests/RunCMake/block/EndMissing-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at EndMissing.cmake:[0-9]+ \(block\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/EndMissing.cmake b/Tests/RunCMake/block/EndMissing.cmake
new file mode 100644
index 0000000..335b64e
--- /dev/null
+++ b/Tests/RunCMake/block/EndMissing.cmake
@@ -0,0 +1 @@
+block()
diff --git a/Tests/RunCMake/block/EndWithArgument-stderr.txt b/Tests/RunCMake/block/EndWithArgument-stderr.txt
new file mode 100644
index 0000000..7586453
--- /dev/null
+++ b/Tests/RunCMake/block/EndWithArgument-stderr.txt
@@ -0,0 +1,9 @@
+CMake Warning \(dev\) in EndWithArgument.cmake:
+ A logical block closing on the line
+
+ .+/Tests/RunCMake/block/EndWithArgument.cmake:[0-9]+ \(endblock\)
+
+ has unexpected arguments.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/block/EndWithArgument.cmake b/Tests/RunCMake/block/EndWithArgument.cmake
new file mode 100644
index 0000000..0641c9a
--- /dev/null
+++ b/Tests/RunCMake/block/EndWithArgument.cmake
@@ -0,0 +1,2 @@
+block()
+endblock(END_ARG)
diff --git a/Tests/RunCMake/block/InvalidArgument-result.txt b/Tests/RunCMake/block/InvalidArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/InvalidArgument-stderr.txt b/Tests/RunCMake/block/InvalidArgument-stderr.txt
new file mode 100644
index 0000000..bee604b
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidArgument-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at InvalidArgument.cmake:[0-9]+ \(block\):
+ block PROPAGATE cannot be specified without a new scope for VARIABLES
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/InvalidArgument.cmake b/Tests/RunCMake/block/InvalidArgument.cmake
new file mode 100644
index 0000000..5269cd0
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidArgument.cmake
@@ -0,0 +1,2 @@
+block(SCOPE_FOR POLICIES PROPAGATE VAR1)
+endblock()
diff --git a/Tests/RunCMake/block/InvalidNesting1-result.txt b/Tests/RunCMake/block/InvalidNesting1-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting1-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/InvalidNesting1-stderr.txt b/Tests/RunCMake/block/InvalidNesting1-stderr.txt
new file mode 100644
index 0000000..6dfe0e1
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting1-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at InvalidNesting1.cmake:[0-9]+ \(else\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/InvalidNesting1.cmake b/Tests/RunCMake/block/InvalidNesting1.cmake
new file mode 100644
index 0000000..27b7944
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting1.cmake
@@ -0,0 +1,6 @@
+
+if (TRUE)
+ block()
+else()
+ endblock()
+endif()
diff --git a/Tests/RunCMake/block/InvalidNesting2-result.txt b/Tests/RunCMake/block/InvalidNesting2-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting2-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/InvalidNesting2-stderr.txt b/Tests/RunCMake/block/InvalidNesting2-stderr.txt
new file mode 100644
index 0000000..71325b6
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting2-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at InvalidNesting2.cmake:[0-9]+ \(endblock\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/InvalidNesting2.cmake b/Tests/RunCMake/block/InvalidNesting2.cmake
new file mode 100644
index 0000000..ae94cdc
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting2.cmake
@@ -0,0 +1,6 @@
+
+block()
+if (TRUE)
+elseif(FALSE)
+endblock()
+endif()
diff --git a/Tests/RunCMake/block/InvalidNesting3-result.txt b/Tests/RunCMake/block/InvalidNesting3-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting3-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/InvalidNesting3-stderr.txt b/Tests/RunCMake/block/InvalidNesting3-stderr.txt
new file mode 100644
index 0000000..344a931
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting3-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at InvalidNesting3.cmake:[0-9]+ \(endwhile\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/InvalidNesting3.cmake b/Tests/RunCMake/block/InvalidNesting3.cmake
new file mode 100644
index 0000000..f692d24
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting3.cmake
@@ -0,0 +1,5 @@
+
+while(TRUE)
+block()
+endwhile()
+endblock()
diff --git a/Tests/RunCMake/block/InvalidNesting4-result.txt b/Tests/RunCMake/block/InvalidNesting4-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting4-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/InvalidNesting4-stderr.txt b/Tests/RunCMake/block/InvalidNesting4-stderr.txt
new file mode 100644
index 0000000..44d6364
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting4-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at InvalidNesting4.cmake:[0-9]+ \(endblock\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/InvalidNesting4.cmake b/Tests/RunCMake/block/InvalidNesting4.cmake
new file mode 100644
index 0000000..6e8e0ae
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting4.cmake
@@ -0,0 +1,5 @@
+
+block()
+foreach(item IN ITEMS A B)
+endblock()
+endforeach()
diff --git a/Tests/RunCMake/block/InvalidNesting5-result.txt b/Tests/RunCMake/block/InvalidNesting5-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting5-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/InvalidNesting5-stderr.txt b/Tests/RunCMake/block/InvalidNesting5-stderr.txt
new file mode 100644
index 0000000..976d2e1
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting5-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at InvalidNesting5.cmake:[0-9]+ \(endfunction\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/InvalidNesting5.cmake b/Tests/RunCMake/block/InvalidNesting5.cmake
new file mode 100644
index 0000000..0479e8d
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting5.cmake
@@ -0,0 +1,5 @@
+
+function(FUNC)
+ block()
+endfunction()
+endblock()
diff --git a/Tests/RunCMake/block/InvalidNesting6-result.txt b/Tests/RunCMake/block/InvalidNesting6-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting6-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/InvalidNesting6-stderr.txt b/Tests/RunCMake/block/InvalidNesting6-stderr.txt
new file mode 100644
index 0000000..2d67b16
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting6-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at InvalidNesting6.cmake:[0-9]+ \(endblock\):
+ Flow control statements are not properly nested.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/InvalidNesting6.cmake b/Tests/RunCMake/block/InvalidNesting6.cmake
new file mode 100644
index 0000000..a1cb359
--- /dev/null
+++ b/Tests/RunCMake/block/InvalidNesting6.cmake
@@ -0,0 +1,5 @@
+
+ block()
+macro(FUNC)
+endblock()
+endmacro()
diff --git a/Tests/RunCMake/block/MissingArgument-result.txt b/Tests/RunCMake/block/MissingArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/MissingArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/MissingArgument-stderr.txt b/Tests/RunCMake/block/MissingArgument-stderr.txt
new file mode 100644
index 0000000..d3e63ca
--- /dev/null
+++ b/Tests/RunCMake/block/MissingArgument-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error at MissingArgument.cmake:[0-9]+ \(block\):
+ Error after keyword "SCOPE_FOR":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/MissingArgument.cmake b/Tests/RunCMake/block/MissingArgument.cmake
new file mode 100644
index 0000000..6018887
--- /dev/null
+++ b/Tests/RunCMake/block/MissingArgument.cmake
@@ -0,0 +1,2 @@
+block(SCOPE_FOR)
+endblock()
diff --git a/Tests/RunCMake/block/RunCMakeTest.cmake b/Tests/RunCMake/block/RunCMakeTest.cmake
new file mode 100644
index 0000000..4260e76
--- /dev/null
+++ b/Tests/RunCMake/block/RunCMakeTest.cmake
@@ -0,0 +1,22 @@
+include(RunCMake)
+
+run_cmake(WrongArgument)
+run_cmake(InvalidArgument)
+run_cmake(MissingArgument)
+run_cmake(WrongScope)
+run_cmake(EndMissing)
+run_cmake(EndWithArgument)
+run_cmake(EndAlone)
+run_cmake(EndAloneWithArgument)
+
+run_cmake(InvalidNesting1)
+run_cmake(InvalidNesting2)
+run_cmake(InvalidNesting3)
+run_cmake(InvalidNesting4)
+run_cmake(InvalidNesting5)
+run_cmake(InvalidNesting6)
+
+run_cmake(Scope)
+run_cmake(Scope-VARIABLES)
+run_cmake(Scope-POLICIES)
+run_cmake(Workflows)
diff --git a/Tests/RunCMake/block/Scope-POLICIES.cmake b/Tests/RunCMake/block/Scope-POLICIES.cmake
new file mode 100644
index 0000000..789b3d9
--- /dev/null
+++ b/Tests/RunCMake/block/Scope-POLICIES.cmake
@@ -0,0 +1,30 @@
+
+set(VAR1 "OUTER1")
+set(VAR2 "OUTER2")
+
+cmake_policy(SET CMP0139 NEW)
+
+# create a block with a new scope for policies
+block(SCOPE_FOR POLICIES)
+ set(VAR1 "INNER1")
+ unset(VAR2)
+ set(VAR3 "INNER3")
+
+ cmake_policy(SET CMP0139 OLD)
+endblock()
+
+# check final values for variables
+if(NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "INNER1")
+ message(SEND_ERROR "block/endblock: VAR1 has unexpected value: ${VAR1}")
+endif()
+if(DEFINED VAR2)
+ message(SEND_ERROR "block/endblock: VAR2 is unexpectedly defined: ${VAR2}")
+endif()
+if(NOT DEFINED VAR3 OR NOT VAR3 STREQUAL "INNER3")
+ message(SEND_ERROR "block/endblock: VAR3 has unexpected value: ${VAR3}")
+endif()
+
+cmake_policy(GET CMP0139 CMP0139_STATUS)
+if(NOT CMP0139_STATUS STREQUAL "NEW")
+ message(SEND_ERROR "block/endblock: CMP0139 has unexpected value: ${CMP0139_STATUS}")
+endif()
diff --git a/Tests/RunCMake/block/Scope-VARIABLES.cmake b/Tests/RunCMake/block/Scope-VARIABLES.cmake
new file mode 100644
index 0000000..140e638
--- /dev/null
+++ b/Tests/RunCMake/block/Scope-VARIABLES.cmake
@@ -0,0 +1,52 @@
+
+set(VAR1 "OUTER1")
+set(VAR2 "OUTER2")
+set(VAR3 "OUTER3")
+set(VAR4 "OUTER4")
+set(VAR5 "OUTER5")
+
+set(VAR6 "CACHE6" CACHE STRING "")
+set(VAR6 "OUTER6")
+
+cmake_policy(SET CMP0139 NEW)
+
+# create a block with a new scope for variables
+block(SCOPE_FOR VARIABLES PROPAGATE VAR3 VAR4 VAR5 VAR6 VAR7)
+ set(VAR1 "INNER1")
+ set(VAR2 "INNER2" PARENT_SCOPE)
+ set(VAR3 "INNER3")
+ unset(VAR4)
+ unset(VAR6)
+ set(VAR7 "INNER7")
+
+ cmake_policy(SET CMP0139 OLD)
+endblock()
+
+# check final values for variables
+if(NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "OUTER1")
+ message(SEND_ERROR "block/endblock: VAR1 has unexpected value: ${VAR1}")
+endif()
+if(NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "INNER2")
+ message(SEND_ERROR "block/endblock: VAR2 has unexpected value: ${VAR2}")
+endif()
+if(NOT DEFINED VAR3 OR NOT VAR3 STREQUAL "INNER3")
+ message(SEND_ERROR "block/endblock: VAR3 has unexpected value: ${VAR3}")
+endif()
+if(DEFINED VAR4)
+ message(SEND_ERROR "block/endblock: VAR4 is unexpectedly defined: ${VAR4}")
+endif()
+if(NOT DEFINED VAR5 OR NOT VAR5 STREQUAL "OUTER5")
+ message(SEND_ERROR "block/endblock: VAR5 has unexpected value: ${VAR5}")
+endif()
+unset(VAR6 CACHE)
+if (DEFINED VAR6)
+ message(SEND_ERROR "block/endblock: VAR6 is unexpectedly defined: ${VAR6}")
+endif()
+if(NOT DEFINED VAR7 OR NOT VAR7 STREQUAL "INNER7")
+ message(SEND_ERROR "block/endblock: VAR7 has unexpected value: ${VAR7}")
+endif()
+
+cmake_policy(GET CMP0139 CMP0139_STATUS)
+if(NOT CMP0139_STATUS STREQUAL "OLD")
+ message(SEND_ERROR "block/endblock: CMP0139 has unexpected value: ${CMP0139_STATUS}")
+endif()
diff --git a/Tests/RunCMake/block/Scope.cmake b/Tests/RunCMake/block/Scope.cmake
new file mode 100644
index 0000000..e1af50a
--- /dev/null
+++ b/Tests/RunCMake/block/Scope.cmake
@@ -0,0 +1,52 @@
+
+set(VAR1 "OUTER1")
+set(VAR2 "OUTER2")
+set(VAR3 "OUTER3")
+set(VAR4 "OUTER4")
+set(VAR5 "OUTER5")
+
+set(VAR6 "CACHE6" CACHE STRING "")
+set(VAR6 "OUTER6")
+
+cmake_policy(SET CMP0139 NEW)
+
+# create a block with a new scope for variables and policies
+block(PROPAGATE VAR3 VAR4 VAR5 VAR6 VAR7)
+ set(VAR1 "INNER1")
+ set(VAR2 "INNER2" PARENT_SCOPE)
+ set(VAR3 "INNER3")
+ unset(VAR4)
+ unset(VAR6)
+ set(VAR7 "INNER7")
+
+ cmake_policy(SET CMP0139 OLD)
+endblock()
+
+# check final values for variables
+if(NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "OUTER1")
+ message(SEND_ERROR "block/endblock: VAR1 has unexpected value: ${VAR1}")
+endif()
+if(NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "INNER2")
+ message(SEND_ERROR "block/endblock: VAR2 has unexpected value: ${VAR2}")
+endif()
+if(NOT DEFINED VAR3 OR NOT VAR3 STREQUAL "INNER3")
+ message(SEND_ERROR "block/endblock: VAR3 has unexpected value: ${VAR3}")
+endif()
+if(DEFINED VAR4)
+ message(SEND_ERROR "block/endblock: VAR4 is unexpectedly defined: ${VAR4}")
+endif()
+if(NOT DEFINED VAR5 OR NOT VAR5 STREQUAL "OUTER5")
+ message(SEND_ERROR "block/endblock: VAR5 has unexpected value: ${VAR5}")
+endif()
+unset(VAR6 CACHE)
+if (DEFINED VAR6)
+ message(SEND_ERROR "block/endblock: VAR6 is unexpectedly defined: ${VAR6}")
+endif()
+if(NOT DEFINED VAR7 OR NOT VAR7 STREQUAL "INNER7")
+ message(SEND_ERROR "block/endblock: VAR6 has unexpected value: ${VAR7}")
+endif()
+
+cmake_policy(GET CMP0139 CMP0139_STATUS)
+if(NOT CMP0139_STATUS STREQUAL "NEW")
+ message(SEND_ERROR "block/endblock: CMP0139 has unexpected value: ${CMP0139_STATUS}")
+endif()
diff --git a/Tests/RunCMake/block/Workflows.cmake b/Tests/RunCMake/block/Workflows.cmake
new file mode 100644
index 0000000..cbf032e
--- /dev/null
+++ b/Tests/RunCMake/block/Workflows.cmake
@@ -0,0 +1,78 @@
+
+set(VAR1 "OUTER1")
+set(VAR2 "OUTER2")
+set(VAR3 "OUTER3")
+
+while (TRUE)
+ # create a block with a new scope for variables
+ block(SCOPE_FOR VARIABLES PROPAGATE VAR3)
+ set(VAR2 "INNER2" PARENT_SCOPE)
+ set(VAR3 "INNER3")
+ break()
+ endblock()
+endwhile()
+
+# check final values for variables
+if(NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "OUTER1")
+ message(SEND_ERROR "block/endblock: VAR1 has unexpected value: ${VAR1}")
+endif()
+if(NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "INNER2")
+ message(SEND_ERROR "block/endblock: VAR2 has unexpected value: ${VAR2}")
+endif()
+if(NOT DEFINED VAR3 OR NOT VAR3 STREQUAL "INNER3")
+ message(SEND_ERROR "block/endblock: VAR3 has unexpected value: ${VAR3}")
+endif()
+
+
+
+set(VAR1 "OUTER1")
+set(VAR2 "OUTER2")
+set(VAR3 "OUTER3")
+
+function (OUTER)
+ # create a block with a new scope for variables
+ block(SCOPE_FOR VARIABLES PROPAGATE VAR3)
+ set(VAR2 "INNER2" PARENT_SCOPE)
+ set(VAR3 "INNER3")
+ return()
+ endblock()
+ set(VAR1 "INNER1" PARENT_SCOPE)
+endfunction()
+outer()
+
+# check final values for variables
+if(NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "OUTER1")
+ message(SEND_ERROR "block/endblock: VAR1 has unexpected value: ${VAR1}")
+endif()
+if(NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "OUTER2")
+ message(SEND_ERROR "block/endblock: VAR2 has unexpected value: ${VAR2}")
+endif()
+if(NOT DEFINED VAR3 OR NOT VAR3 STREQUAL "OUTER3")
+ message(SEND_ERROR "block/endblock: VAR3 has unexpected value: ${VAR3}")
+endif()
+
+
+
+set(VAR1 "OUTER1")
+set(VAR2 "OUTER2")
+set(VAR3 "OUTER3")
+
+foreach (id IN ITEMS 1 2 3)
+ # create a block with a new scope for variables
+ block(SCOPE_FOR VARIABLES PROPAGATE VAR${id})
+ set(VAR${id} "INNER${id}")
+ continue()
+ set(VAR${id} "BAD${id}")
+ endblock()
+endforeach()
+
+# check final values for variables
+if(NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "INNER1")
+ message(SEND_ERROR "block/endblock: VAR1 has unexpected value: ${VAR1}")
+endif()
+if(NOT DEFINED VAR2 OR NOT VAR2 STREQUAL "INNER2")
+ message(SEND_ERROR "block/endblock: VAR2 has unexpected value: ${VAR2}")
+endif()
+if(NOT DEFINED VAR3 OR NOT VAR3 STREQUAL "INNER3")
+ message(SEND_ERROR "block/endblock: VAR3 has unexpected value: ${VAR3}")
+endif()
diff --git a/Tests/RunCMake/block/WrongArgument-result.txt b/Tests/RunCMake/block/WrongArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/WrongArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/WrongArgument-stderr.txt b/Tests/RunCMake/block/WrongArgument-stderr.txt
new file mode 100644
index 0000000..56faea7
--- /dev/null
+++ b/Tests/RunCMake/block/WrongArgument-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at WrongArgument.cmake:[0-9]+ \(block\):
+ block called with unsupported argument "WRONG_ARG"
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/WrongArgument.cmake b/Tests/RunCMake/block/WrongArgument.cmake
new file mode 100644
index 0000000..e460866
--- /dev/null
+++ b/Tests/RunCMake/block/WrongArgument.cmake
@@ -0,0 +1,2 @@
+block(WRONG_ARG)
+endblock()
diff --git a/Tests/RunCMake/block/WrongScope-result.txt b/Tests/RunCMake/block/WrongScope-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/block/WrongScope-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/block/WrongScope-stderr.txt b/Tests/RunCMake/block/WrongScope-stderr.txt
new file mode 100644
index 0000000..dd2a1ef
--- /dev/null
+++ b/Tests/RunCMake/block/WrongScope-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at WrongScope.cmake:[0-9]+ \(block\):
+ block SCOPE_FOR unsupported scope "WRONG_SCOPE"
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/block/WrongScope.cmake b/Tests/RunCMake/block/WrongScope.cmake
new file mode 100644
index 0000000..97a6783
--- /dev/null
+++ b/Tests/RunCMake/block/WrongScope.cmake
@@ -0,0 +1,2 @@
+block(SCOPE_FOR WRONG_SCOPE)
+endblock()
diff --git a/Tests/RunCMake/cmake_host_system_information/Registry_BadQuery2-stderr.txt b/Tests/RunCMake/cmake_host_system_information/Registry_BadQuery2-stderr.txt
index 6a430f1..ea1566d 100644
--- a/Tests/RunCMake/cmake_host_system_information/Registry_BadQuery2-stderr.txt
+++ b/Tests/RunCMake/cmake_host_system_information/Registry_BadQuery2-stderr.txt
@@ -1,5 +1,7 @@
CMake Error at Registry_BadQuery2.cmake:[0-9]+ \(cmake_host_system_information\):
- cmake_host_system_information missing expected value for argument\(s\)
- "VALUE".
+ Error after keyword "VALUE":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/cmake_host_system_information/Registry_BadView1-stderr.txt b/Tests/RunCMake/cmake_host_system_information/Registry_BadView1-stderr.txt
index 5eda4ff..f8c96d8 100644
--- a/Tests/RunCMake/cmake_host_system_information/Registry_BadView1-stderr.txt
+++ b/Tests/RunCMake/cmake_host_system_information/Registry_BadView1-stderr.txt
@@ -1,5 +1,7 @@
CMake Error at Registry_BadView1.cmake:[0-9]+ \(cmake_host_system_information\):
- cmake_host_system_information missing expected value for argument\(s\)
- "VIEW".
+ Error after keyword "VIEW":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/cmake_language/RunCMakeTest.cmake b/Tests/RunCMake/cmake_language/RunCMakeTest.cmake
index 6480b2e..38ce10b 100644
--- a/Tests/RunCMake/cmake_language/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_language/RunCMakeTest.cmake
@@ -8,6 +8,7 @@ foreach(command IN ITEMS
"if" "elseif" "else" "endif"
"while" "endwhile"
"foreach" "endforeach"
+ "block" "endblock"
)
message(STATUS "Running call_invalid_command for ${command}...")
run_cmake_with_options(call_invalid_command -Dcommand=${command})
@@ -42,6 +43,7 @@ foreach(command IN ITEMS
"if" "elseif" "else" "endif"
"while" "endwhile"
"foreach" "endforeach"
+ "block" "endblock"
"return"
)
message(STATUS "Running defer_call_invalid_command for ${command}...")
@@ -82,3 +84,61 @@ run_cmake(defer_get_call_id_var)
run_cmake(defer_missing_arg)
run_cmake(defer_missing_call)
run_cmake(defer_unknown_option)
+
+# Default log level
+run_cmake_command(
+ get_message_log_level_none
+ ${CMAKE_COMMAND}
+ -P ${RunCMake_SOURCE_DIR}/get_message_log_level.cmake
+ )
+
+# Log level from cache
+run_cmake_command(
+ get_message_log_level_cache
+ ${CMAKE_COMMAND}
+ -DCMAKE_MESSAGE_LOG_LEVEL=TRACE
+ -P ${RunCMake_SOURCE_DIR}/get_message_log_level.cmake
+ )
+
+# Log level from regular variable
+run_cmake_command(
+ get_message_log_level_var
+ ${CMAKE_COMMAND}
+ -DNEW_LOG_LEVEL=TRACE
+ -P ${RunCMake_SOURCE_DIR}/get_message_log_level.cmake
+ )
+
+# Log level from command line
+run_cmake_command(
+ get_message_log_level_cli
+ ${CMAKE_COMMAND}
+ --log-level=DEBUG
+ -P ${RunCMake_SOURCE_DIR}/get_message_log_level.cmake
+ )
+
+# Log level from command line, it has higher priority over a cache variable
+run_cmake_command(
+ get_message_log_level_cli_and_cache
+ ${CMAKE_COMMAND}
+ --log-level=DEBUG
+ -DCMAKE_MESSAGE_LOG_LEVEL=TRACE
+ -P ${RunCMake_SOURCE_DIR}/get_message_log_level.cmake
+ )
+
+# Log level from command line, it has higher priority over a regular variable
+run_cmake_command(
+ get_message_log_level_cli_and_var
+ ${CMAKE_COMMAND}
+ --log-level=DEBUG
+ -DNEW_LOG_LEVEL=TRACE
+ -P ${RunCMake_SOURCE_DIR}/get_message_log_level.cmake
+ )
+
+# Log level from variable, it has higher priority over a cache variable
+run_cmake_command(
+ get_message_log_level_var_and_cache
+ ${CMAKE_COMMAND}
+ -DNEW_LOG_LEVEL=DEBUG
+ -DCMAKE_MESSAGE_LOG_LEVEL=TRACE
+ -P ${RunCMake_SOURCE_DIR}/get_message_log_level.cmake
+ )
diff --git a/Tests/RunCMake/cmake_language/get_message_log_level.cmake b/Tests/RunCMake/cmake_language/get_message_log_level.cmake
new file mode 100644
index 0000000..1740c1f
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/get_message_log_level.cmake
@@ -0,0 +1,5 @@
+if(NEW_LOG_LEVEL)
+ set(CMAKE_MESSAGE_LOG_LEVEL "${NEW_LOG_LEVEL}")
+endif()
+cmake_language(GET_MESSAGE_LOG_LEVEL log_level)
+message(STATUS "log level is: ${log_level}")
diff --git a/Tests/RunCMake/cmake_language/get_message_log_level_cache-stdout.txt b/Tests/RunCMake/cmake_language/get_message_log_level_cache-stdout.txt
new file mode 100644
index 0000000..cf1cd7b
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/get_message_log_level_cache-stdout.txt
@@ -0,0 +1 @@
+log level is: TRACE
diff --git a/Tests/RunCMake/cmake_language/get_message_log_level_cli-stdout.txt b/Tests/RunCMake/cmake_language/get_message_log_level_cli-stdout.txt
new file mode 100644
index 0000000..4d6e1eb
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/get_message_log_level_cli-stdout.txt
@@ -0,0 +1 @@
+log level is: DEBUG
diff --git a/Tests/RunCMake/cmake_language/get_message_log_level_cli_and_cache-stdout.txt b/Tests/RunCMake/cmake_language/get_message_log_level_cli_and_cache-stdout.txt
new file mode 100644
index 0000000..4d6e1eb
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/get_message_log_level_cli_and_cache-stdout.txt
@@ -0,0 +1 @@
+log level is: DEBUG
diff --git a/Tests/RunCMake/cmake_language/get_message_log_level_cli_and_var-stdout.txt b/Tests/RunCMake/cmake_language/get_message_log_level_cli_and_var-stdout.txt
new file mode 100644
index 0000000..4d6e1eb
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/get_message_log_level_cli_and_var-stdout.txt
@@ -0,0 +1 @@
+log level is: DEBUG
diff --git a/Tests/RunCMake/cmake_language/get_message_log_level_none-stdout.txt b/Tests/RunCMake/cmake_language/get_message_log_level_none-stdout.txt
new file mode 100644
index 0000000..92ffd34
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/get_message_log_level_none-stdout.txt
@@ -0,0 +1 @@
+log level is: STATUS
diff --git a/Tests/RunCMake/cmake_language/get_message_log_level_var-stdout.txt b/Tests/RunCMake/cmake_language/get_message_log_level_var-stdout.txt
new file mode 100644
index 0000000..cf1cd7b
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/get_message_log_level_var-stdout.txt
@@ -0,0 +1 @@
+log level is: TRACE
diff --git a/Tests/RunCMake/cmake_language/get_message_log_level_var_and_cache-stdout.txt b/Tests/RunCMake/cmake_language/get_message_log_level_var_and_cache-stdout.txt
new file mode 100644
index 0000000..4d6e1eb
--- /dev/null
+++ b/Tests/RunCMake/cmake_language/get_message_log_level_var_and_cache-stdout.txt
@@ -0,0 +1 @@
+log level is: DEBUG
diff --git a/Tests/RunCMake/cmake_path/BASE_DIRECTORY-no-arg-stderr.txt b/Tests/RunCMake/cmake_path/BASE_DIRECTORY-no-arg-stderr.txt
new file mode 100644
index 0000000..ad7d134
--- /dev/null
+++ b/Tests/RunCMake/cmake_path/BASE_DIRECTORY-no-arg-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at .+/cmake_path/call-cmake_path.cmake:[0-9]+ \(cmake_path\):
+ Error after keyword "BASE_DIRECTORY":
+
+ missing required value
diff --git a/Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-empty-stderr.txt b/Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-empty-stderr.txt
new file mode 100644
index 0000000..f1b52cc
--- /dev/null
+++ b/Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-empty-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at .+/call-cmake_path.cmake:[0-9]+ \(cmake_path\):
+ Error after keyword "OUTPUT_VARIABLE":
+
+ empty string not allowed
diff --git a/Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-no-arg-stderr.txt b/Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-no-arg-stderr.txt
index e1d6592..63289ef 100644
--- a/Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-no-arg-stderr.txt
+++ b/Tests/RunCMake/cmake_path/OUTPUT_VARIABLE-no-arg-stderr.txt
@@ -1,2 +1,4 @@
CMake Error at .+/cmake_path/call-cmake_path.cmake:[0-9]+ \(cmake_path\):
- cmake_path OUTPUT_VARIABLE requires an argument.
+ Error after keyword "OUTPUT_VARIABLE":
+
+ missing required value
diff --git a/Tests/RunCMake/cmake_path/RunCMakeTest.cmake b/Tests/RunCMake/cmake_path/RunCMakeTest.cmake
index 991f46b..1742b06 100644
--- a/Tests/RunCMake/cmake_path/RunCMakeTest.cmake
+++ b/Tests/RunCMake/cmake_path/RunCMakeTest.cmake
@@ -74,6 +74,14 @@ foreach (command IN ITEMS APPEND APPEND_STRING REMOVE_FILENAME REPLACE_FILENAME
endforeach()
+## BASE_DIRECTORY without argument
+set (RunCMake-stderr-file "BASE_DIRECTORY-no-arg-stderr.txt")
+
+foreach (command IN ITEMS RELATIVE_PATH ABSOLUTE_PATH)
+ run_cmake_command (${command}-OUTPUT_VARIABLE-no-arg "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=${command} path BASE_DIRECTORY" -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
+endforeach()
+
+
## Invalid output variable
set (RunCMake-stderr-file "invalid-output-var-stderr.txt")
@@ -106,6 +114,9 @@ foreach (command IN ITEMS NATIVE_PATH
run_cmake_command (${command}-invalid-output "${CMAKE_COMMAND}" "-DCMAKE_PATH_ARGUMENTS=${command} path ${extra_args}" -DCHECK_INVALID_OUTPUT=ON -P "${RunCMake_SOURCE_DIR}/call-cmake_path.cmake")
endforeach()
+# OUTPUT_VARIABLE empty name
+set (RunCMake-stderr-file "OUTPUT_VARIABLE-empty-stderr.txt")
+
foreach (command IN ITEMS APPEND APPEND_STRING REMOVE_FILENAME REPLACE_FILENAME
REMOVE_EXTENSION REPLACE_EXTENSION NORMAL_PATH
RELATIVE_PATH ABSOLUTE_PATH)
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop-result.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop-stdout.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop-stdout.txt
new file mode 100644
index 0000000..a7eae05
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop-stdout.txt
@@ -0,0 +1 @@
+CTEST_TEST_VAR=set-via-ENVIRONMENT-property
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop.cmake b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop.cmake
new file mode 100644
index 0000000..51e7f2a
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-prop.cmake
@@ -0,0 +1,9 @@
+include(CTest)
+
+add_test(NAME cmake_environment COMMAND "${CMAKE_COMMAND}" -E environment)
+set_tests_properties(
+ cmake_environment
+ PROPERTIES
+ ENVIRONMENT "CTEST_TEST_VAR=set-via-ENVIRONMENT-property"
+ ENVIRONMENT_MODIFICATION "CTEST_TEST_VAR=set:set-via-ENVIRONMENT_MODIFICATION;CTEST_TEST_VAR=reset:"
+)
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system-result.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system-stdout.txt b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system-stdout.txt
new file mode 100644
index 0000000..beaf133
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system-stdout.txt
@@ -0,0 +1 @@
+CTEST_TEST_VAR=set-via-system-environment
diff --git a/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system.cmake b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system.cmake
new file mode 100644
index 0000000..23268aa
--- /dev/null
+++ b/Tests/RunCMake/ctest_environment/ENVIRONMENT_MODIFICATION-reset-to-system.cmake
@@ -0,0 +1,9 @@
+include(CTest)
+
+add_test(NAME cmake_environment COMMAND "${CMAKE_COMMAND}" -E environment)
+set_tests_properties(
+ cmake_environment
+ PROPERTIES
+ # ENVIRONMENT "CTEST_TEST_VAR=set-via-ENVIRONMENT-property"
+ ENVIRONMENT_MODIFICATION "CTEST_TEST_VAR=set:set-via-ENVIRONMENT_MODIFICATION;CTEST_TEST_VAR=reset:"
+)
diff --git a/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake b/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
index 3447779..365c9e8 100644
--- a/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
+++ b/Tests/RunCMake/ctest_environment/RunCMakeTest.cmake
@@ -10,3 +10,7 @@ set(RunCTest_VERBOSE_FLAG "-VV")
run_ctest(ENVIRONMENT_MODIFICATION-invalid-op)
run_ctest(ENVIRONMENT_MODIFICATION-no-colon)
run_ctest(ENVIRONMENT_MODIFICATION-no-equals)
+
+set(ENV{CTEST_TEST_VAR} set-via-system-environment)
+run_ctest(ENVIRONMENT_MODIFICATION-reset-to-prop)
+run_ctest(ENVIRONMENT_MODIFICATION-reset-to-system)
diff --git a/Tests/RunCMake/execute_process/EchoCommand3-stderr.txt b/Tests/RunCMake/execute_process/EchoCommand3-stderr.txt
index e27f1e6..62cad52 100644
--- a/Tests/RunCMake/execute_process/EchoCommand3-stderr.txt
+++ b/Tests/RunCMake/execute_process/EchoCommand3-stderr.txt
@@ -1,2 +1,4 @@
CMake Error at .*EchoCommand.cmake:.*\(execute_process\):
- execute_process called with no value for COMMAND_ECHO.
+ Error after keyword "COMMAND_ECHO":
+
+ missing required value
diff --git a/Tests/RunCMake/execute_process/EncodingMissing-stderr.txt b/Tests/RunCMake/execute_process/EncodingMissing-stderr.txt
index 1a69579..7f85654 100644
--- a/Tests/RunCMake/execute_process/EncodingMissing-stderr.txt
+++ b/Tests/RunCMake/execute_process/EncodingMissing-stderr.txt
@@ -1,4 +1,7 @@
^CMake Error at EncodingMissing.cmake:[0-9]+ \(execute_process\):
- execute_process called with no value for ENCODING.
+ Error after keyword "ENCODING":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-stderr.txt
deleted file mode 100644
index b22387b..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms-stderr.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-CMake Error at CHMOD-all-perms\.cmake:[0-9]+ \(file\):
- file Remove either PERMISSIONS or FILE_PERMISSIONS or DIRECTORY_PERMISSIONS
- from the invocation
-Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-all-perms.cmake
deleted file mode 100644
index b49583d..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-all-perms.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-
-file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
-file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ
- FILE_PERMISSIONS OWNER_READ DIRECTORY_PERMISSIONS OWNER_READ)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-stderr.txt
deleted file mode 100644
index 8d09e35..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path-stderr.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-CMake Error at CHMOD-invalid-path\.cmake:[0-9]+ \(file\):
- file does not exist:
-
- .*/chmod-tests/I_dont_exist
-Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path.cmake
deleted file mode 100644
index 36915c1..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-path.cmake
+++ /dev/null
@@ -1,4 +0,0 @@
-file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-
-file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/I_dont_exist PERMISSIONS OWNER_READ)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-stderr.txt
deleted file mode 100644
index 84ba2a2..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error at CHMOD-invalid-perms\.cmake:[0-9]+ \(file\):
- file INVALID_PERMISSION is an invalid permission specifier
-Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms.cmake
deleted file mode 100644
index 22cab0b..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-invalid-perms.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-
-file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
-file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS INVALID_PERMISSION)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-stderr.txt
deleted file mode 100644
index 2c248f8..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error at CHMOD-no-keyword\.cmake:[0-9]+ \(file\):
- file No permissions given
-Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword.cmake
deleted file mode 100644
index 8b62106..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-no-keyword.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-
-file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
-file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-stderr.txt
deleted file mode 100644
index a18609f..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms-stderr.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-CMake Error at CHMOD-no-perms\.cmake:[0-9]+ \(file\):
- file No permissions given
-Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-no-perms.cmake
deleted file mode 100644
index 9fbd359..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-no-perms.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-
-file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
-file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-ok.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-ok.cmake
deleted file mode 100644
index 87e3e57..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-ok.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-
-file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
-file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-override.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-override.cmake
deleted file mode 100644
index d9226b8..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-override.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-
-file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a)
-file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_READ
- FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-write-only-stderr.txt b/Tests/RunCMake/file-CHMOD/CHMOD-write-only-stderr.txt
deleted file mode 100644
index 1c87a59..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-write-only-stderr.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-CMake Error at CHMOD-write-only\.cmake:[0-9]+ \(file\):
- file failed to open for reading \(Permission denied\):
-
- .*/chmod-tests/a
-Call Stack \(most recent call first\):
- CMakeLists\.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/file-CHMOD/CHMOD-write-only.cmake b/Tests/RunCMake/file-CHMOD/CHMOD-write-only.cmake
deleted file mode 100644
index 1289efc..0000000
--- a/Tests/RunCMake/file-CHMOD/CHMOD-write-only.cmake
+++ /dev/null
@@ -1,6 +0,0 @@
-file(REMOVE_RECURSE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests)
-
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a "CONTENT")
-file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a PERMISSIONS OWNER_WRITE)
-file(READ ${CMAKE_CURRENT_BINARY_DIR}/chmod-tests/a content)
diff --git a/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake b/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake
index 18deb89..e6b1169 100644
--- a/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file-CHMOD/RunCMakeTest.cmake
@@ -1,12 +1,14 @@
include(RunCMake)
-run_cmake(CHMOD-no-perms)
-run_cmake(CHMOD-no-keyword)
-run_cmake(CHMOD-all-perms)
-run_cmake(CHMOD-invalid-perms)
-run_cmake(CHMOD-invalid-path)
-run_cmake(CHMOD-ok)
-run_cmake(CHMOD-override)
+run_cmake_script(no-perms)
+run_cmake_script(missing-perms)
+run_cmake_script(missing-file-perms)
+run_cmake_script(missing-dir-perms)
+run_cmake_script(all-perms)
+run_cmake_script(invalid-perms)
+run_cmake_script(invalid-path)
+run_cmake_script(ok)
+run_cmake_script(override)
if(UNIX)
execute_process(COMMAND id -u $ENV{USER}
@@ -15,5 +17,5 @@ if(UNIX)
endif()
if(NOT WIN32 AND NOT MSYS AND NOT "${uid}" STREQUAL "0")
- run_cmake(CHMOD-write-only)
+ run_cmake_script(write-only)
endif()
diff --git a/Tests/RunCMake/file-CHMOD/all-perms-result.txt b/Tests/RunCMake/file-CHMOD/all-perms-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/all-perms-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-CHMOD/all-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/all-perms-stderr.txt
new file mode 100644
index 0000000..6932a1f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/all-perms-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at [^
+]*/all-perms\.cmake:[0-9]+ \(file\):
+ file Remove either PERMISSIONS or FILE_PERMISSIONS or DIRECTORY_PERMISSIONS
+ from the invocation$
diff --git a/Tests/RunCMake/file-CHMOD/all-perms.cmake b/Tests/RunCMake/file-CHMOD/all-perms.cmake
new file mode 100644
index 0000000..5ff81b8
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/all-perms.cmake
@@ -0,0 +1,3 @@
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ
+ FILE_PERMISSIONS OWNER_READ DIRECTORY_PERMISSIONS OWNER_READ)
diff --git a/Tests/RunCMake/file-CHMOD/invalid-path-result.txt b/Tests/RunCMake/file-CHMOD/invalid-path-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/invalid-path-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-CHMOD/invalid-path-stderr.txt b/Tests/RunCMake/file-CHMOD/invalid-path-stderr.txt
new file mode 100644
index 0000000..eb5fb31
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/invalid-path-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at [^
+]*/invalid-path\.cmake:[0-9]+ \(file\):
+ file does not exist:
+
+ [^
+]*/Tests/RunCMake/file-CHMOD/invalid-path-build/I_dont_exist$
diff --git a/Tests/RunCMake/file-CHMOD/invalid-path.cmake b/Tests/RunCMake/file-CHMOD/invalid-path.cmake
new file mode 100644
index 0000000..e8b0313
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/invalid-path.cmake
@@ -0,0 +1 @@
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/I_dont_exist PERMISSIONS OWNER_READ)
diff --git a/Tests/RunCMake/file-CHMOD/invalid-perms-result.txt b/Tests/RunCMake/file-CHMOD/invalid-perms-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/invalid-perms-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-CHMOD/invalid-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/invalid-perms-stderr.txt
new file mode 100644
index 0000000..daab22e
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/invalid-perms-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error at [^
+]*/invalid-perms\.cmake:[0-9]+ \(file\):
+ file INVALID_PERMISSION is an invalid permission specifier$
diff --git a/Tests/RunCMake/file-CHMOD/invalid-perms.cmake b/Tests/RunCMake/file-CHMOD/invalid-perms.cmake
new file mode 100644
index 0000000..42129b9
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/invalid-perms.cmake
@@ -0,0 +1,2 @@
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS INVALID_PERMISSION)
diff --git a/Tests/RunCMake/file-CHMOD/missing-dir-perms-result.txt b/Tests/RunCMake/file-CHMOD/missing-dir-perms-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-dir-perms-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-CHMOD/missing-dir-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/missing-dir-perms-stderr.txt
new file mode 100644
index 0000000..c05bb2d
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-dir-perms-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at [^
+]*/missing-dir-perms.cmake:[0-9]+ \(file\):
+ Error after keyword "DIRECTORY_PERMISSIONS":
+
+ missing required value$
diff --git a/Tests/RunCMake/file-CHMOD/missing-dir-perms.cmake b/Tests/RunCMake/file-CHMOD/missing-dir-perms.cmake
new file mode 100644
index 0000000..9d0fdad
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-dir-perms.cmake
@@ -0,0 +1,2 @@
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ DIRECTORY_PERMISSIONS)
diff --git a/Tests/RunCMake/file-CHMOD/missing-file-perms-result.txt b/Tests/RunCMake/file-CHMOD/missing-file-perms-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-file-perms-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-CHMOD/missing-file-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/missing-file-perms-stderr.txt
new file mode 100644
index 0000000..c3f4f0f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-file-perms-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at [^
+]*/missing-file-perms.cmake:[0-9]+ \(file\):
+ Error after keyword "FILE_PERMISSIONS":
+
+ missing required value$
diff --git a/Tests/RunCMake/file-CHMOD/missing-file-perms.cmake b/Tests/RunCMake/file-CHMOD/missing-file-perms.cmake
new file mode 100644
index 0000000..bcf35aa
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-file-perms.cmake
@@ -0,0 +1,2 @@
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ FILE_PERMISSIONS)
diff --git a/Tests/RunCMake/file-CHMOD/missing-perms-result.txt b/Tests/RunCMake/file-CHMOD/missing-perms-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-perms-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-CHMOD/missing-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/missing-perms-stderr.txt
new file mode 100644
index 0000000..1508b13
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-perms-stderr.txt
@@ -0,0 +1,5 @@
+^CMake Error at [^
+]*/missing-perms.cmake:[0-9]+ \(file\):
+ Error after keyword "PERMISSIONS":
+
+ missing required value$
diff --git a/Tests/RunCMake/file-CHMOD/missing-perms.cmake b/Tests/RunCMake/file-CHMOD/missing-perms.cmake
new file mode 100644
index 0000000..da9f182
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/missing-perms.cmake
@@ -0,0 +1,2 @@
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a FILE_PERMISSIONS OWNER_READ PERMISSIONS)
diff --git a/Tests/RunCMake/file-CHMOD/no-perms-result.txt b/Tests/RunCMake/file-CHMOD/no-perms-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/no-perms-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-CHMOD/no-perms-stderr.txt b/Tests/RunCMake/file-CHMOD/no-perms-stderr.txt
new file mode 100644
index 0000000..4c5a139
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/no-perms-stderr.txt
@@ -0,0 +1,3 @@
+^CMake Error at [^
+]*/no-perms\.cmake:[0-9]+ \(file\):
+ file No permissions given$
diff --git a/Tests/RunCMake/file-CHMOD/no-perms.cmake b/Tests/RunCMake/file-CHMOD/no-perms.cmake
new file mode 100644
index 0000000..602cfc2
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/no-perms.cmake
@@ -0,0 +1,2 @@
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a)
diff --git a/Tests/RunCMake/file-CHMOD/ok.cmake b/Tests/RunCMake/file-CHMOD/ok.cmake
new file mode 100644
index 0000000..7c74d27
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/ok.cmake
@@ -0,0 +1,2 @@
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ)
diff --git a/Tests/RunCMake/file-CHMOD/override.cmake b/Tests/RunCMake/file-CHMOD/override.cmake
new file mode 100644
index 0000000..67e5a23
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/override.cmake
@@ -0,0 +1,3 @@
+file(TOUCH ${CMAKE_CURRENT_BINARY_DIR}/a)
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_READ
+ FILE_PERMISSIONS OWNER_READ OWNER_WRITE)
diff --git a/Tests/RunCMake/file-CHMOD/write-only-result.txt b/Tests/RunCMake/file-CHMOD/write-only-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/write-only-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/file-CHMOD/write-only-stderr.txt b/Tests/RunCMake/file-CHMOD/write-only-stderr.txt
new file mode 100644
index 0000000..169a092
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/write-only-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at [^
+]*/write-only\.cmake:[0-9]+ \(file\):
+ file failed to open for reading \(Permission denied\):
+
+ [^
+]*/Tests/RunCMake/file-CHMOD/write-only-build/a$
diff --git a/Tests/RunCMake/file-CHMOD/write-only.cmake b/Tests/RunCMake/file-CHMOD/write-only.cmake
new file mode 100644
index 0000000..aa9d803
--- /dev/null
+++ b/Tests/RunCMake/file-CHMOD/write-only.cmake
@@ -0,0 +1,3 @@
+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/a "CONTENT")
+file(CHMOD ${CMAKE_CURRENT_BINARY_DIR}/a PERMISSIONS OWNER_WRITE)
+file(READ ${CMAKE_CURRENT_BINARY_DIR}/a content)
diff --git a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt
index c6ad3d0..39f307d 100644
--- a/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt
+++ b/Tests/RunCMake/file-GET_RUNTIME_DEPENDENCIES/badargs2-stderr.txt
@@ -13,11 +13,21 @@ Call Stack \(most recent call first\):
This warning is for project developers\. Use -Wno-dev to suppress it\.
CMake Error at badargs2\.cmake:[0-9]+ \(file\):
- file Keywords missing values:
+ Error after keyword "BUNDLE_EXECUTABLE":
+
+ missing required value
+
+ Error after keyword "CONFLICTING_DEPENDENCIES_PREFIX":
+
+ missing required value
+
+ Error after keyword "RESOLVED_DEPENDENCIES_VAR":
+
+ missing required value
+
+ Error after keyword "UNRESOLVED_DEPENDENCIES_VAR":
+
+ missing required value
- RESOLVED_DEPENDENCIES_VAR
- UNRESOLVED_DEPENDENCIES_VAR
- CONFLICTING_DEPENDENCIES_PREFIX
- BUNDLE_EXECUTABLE
Call Stack \(most recent call first\):
CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt b/Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt
index 7c58aeb..54a3e5a 100644
--- a/Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt
+++ b/Tests/RunCMake/file/REAL_PATH-no-base-dir-stderr.txt
@@ -1,2 +1,7 @@
-CMake Error at REAL_PATH-no-base-dir.cmake:[0-9]+ \(file\):
- file BASE_DIRECTORY requires a value
+^CMake Error at REAL_PATH-no-base-dir.cmake:[0-9]+ \(file\):
+ Error after keyword "BASE_DIRECTORY":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/file/RunCMakeTest.cmake b/Tests/RunCMake/file/RunCMakeTest.cmake
index aff4735..db88956 100644
--- a/Tests/RunCMake/file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/file/RunCMakeTest.cmake
@@ -47,6 +47,7 @@ run_cmake(GLOB_RECURSE)
run_cmake(GLOB_RECURSE-noexp-FOLLOW_SYMLINKS)
run_cmake(SIZE)
run_cmake(SIZE-error-does-not-exist)
+run_cmake(TIMESTAMP)
run_cmake(REMOVE-empty)
diff --git a/Tests/RunCMake/file/TIMESTAMP-stdout.txt b/Tests/RunCMake/file/TIMESTAMP-stdout.txt
new file mode 100644
index 0000000..42be6ba
--- /dev/null
+++ b/Tests/RunCMake/file/TIMESTAMP-stdout.txt
@@ -0,0 +1 @@
+-- '[0-9]*-[01][0-9]-[0-3][0-9]T[0-2][0-9]:[0-5][0-9]:[0-6][0-9]Z'
diff --git a/Tests/RunCMake/file/TIMESTAMP.cmake b/Tests/RunCMake/file/TIMESTAMP.cmake
new file mode 100644
index 0000000..2bd2577
--- /dev/null
+++ b/Tests/RunCMake/file/TIMESTAMP.cmake
@@ -0,0 +1,2 @@
+file(TIMESTAMP "TIMESTAMP.cmake" output UTC)
+message(STATUS "'${output}'")
diff --git a/Tests/RunCMake/find_file/RunCMakeTest.cmake b/Tests/RunCMake/find_file/RunCMakeTest.cmake
index 23765d4..296bb71 100644
--- a/Tests/RunCMake/find_file/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_file/RunCMakeTest.cmake
@@ -7,6 +7,10 @@ run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
+run_cmake(VALIDATOR-no-function)
+run_cmake(VALIDATOR-undefined-function)
+run_cmake(VALIDATOR-specify-macro)
+run_cmake(VALIDATOR)
run_cmake_with_options(FromPATHEnvDebugVar --debug-find-var=PrefixInPATH_File)
diff --git a/Tests/RunCMake/find_file/VALIDATOR-no-function-result.txt b/Tests/RunCMake/find_file/VALIDATOR-no-function-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-no-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_file/VALIDATOR-no-function-stderr.txt b/Tests/RunCMake/find_file/VALIDATOR-no-function-stderr.txt
new file mode 100644
index 0000000..4d49649
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-no-function-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_file\):
+ find_file missing required argument for "VALIDATOR"
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_file/VALIDATOR-no-function.cmake b/Tests/RunCMake/find_file/VALIDATOR-no-function.cmake
new file mode 100644
index 0000000..4800fe9
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-no-function.cmake
@@ -0,0 +1,2 @@
+
+find_file(result NAMES input.txt VALIDATOR)
diff --git a/Tests/RunCMake/find_file/VALIDATOR-specify-macro-result.txt b/Tests/RunCMake/find_file/VALIDATOR-specify-macro-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-specify-macro-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_file/VALIDATOR-specify-macro-stderr.txt b/Tests/RunCMake/find_file/VALIDATOR-specify-macro-stderr.txt
new file mode 100644
index 0000000..7e0eda0
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-specify-macro-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_file\):
+ find_file command specified for "VALIDATOR" is not a function: check.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_file/VALIDATOR-specify-macro.cmake b/Tests/RunCMake/find_file/VALIDATOR-specify-macro.cmake
new file mode 100644
index 0000000..ec0ce9a
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-specify-macro.cmake
@@ -0,0 +1,5 @@
+
+macro(CHECK result path)
+endmacro()
+
+find_file(result NAMES input.txt VALIDATOR check)
diff --git a/Tests/RunCMake/find_file/VALIDATOR-stderr.txt b/Tests/RunCMake/find_file/VALIDATOR-stderr.txt
new file mode 100644
index 0000000..6c8159b
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-stderr.txt
@@ -0,0 +1,3 @@
+CHECK='[^']+/Tests/RunCMake/find_file/include/PrefixInPATH.h'
+CHECK='[^']+/Tests/RunCMake/find_file/include/PrefixInPATH.h'
+CHECK='[^']+/Tests/RunCMake/find_file/include/PrefixInPATH.h'
diff --git a/Tests/RunCMake/find_file/VALIDATOR-stdout.txt b/Tests/RunCMake/find_file/VALIDATOR-stdout.txt
new file mode 100644
index 0000000..44fa77c
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-stdout.txt
@@ -0,0 +1,3 @@
+-- FILE='[^']+/Tests/RunCMake/find_file/include/PrefixInPATH.h'
+-- FILE='[^']+/Tests/RunCMake/find_file/include/PrefixInPATH.h'
+-- FILE='FILE-NOTFOUND'
diff --git a/Tests/RunCMake/find_file/VALIDATOR-undefined-function-result.txt b/Tests/RunCMake/find_file/VALIDATOR-undefined-function-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-undefined-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_file/VALIDATOR-undefined-function-stderr.txt b/Tests/RunCMake/find_file/VALIDATOR-undefined-function-stderr.txt
new file mode 100644
index 0000000..b4125e6
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-undefined-function-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_file\):
+ find_file command specified for "VALIDATOR" is undefined: undefined.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_file/VALIDATOR-undefined-function.cmake b/Tests/RunCMake/find_file/VALIDATOR-undefined-function.cmake
new file mode 100644
index 0000000..c465887
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR-undefined-function.cmake
@@ -0,0 +1,2 @@
+
+find_file(result NAMES input.txt VALIDATOR undefined)
diff --git a/Tests/RunCMake/find_file/VALIDATOR.cmake b/Tests/RunCMake/find_file/VALIDATOR.cmake
new file mode 100644
index 0000000..72dd8f9
--- /dev/null
+++ b/Tests/RunCMake/find_file/VALIDATOR.cmake
@@ -0,0 +1,39 @@
+
+function(CHECK_DEFAULT result filename)
+ message("CHECK='${filename}'")
+endfunction()
+
+function(CHECK_OK result filename)
+ message("CHECK='${filename}'")
+ set(${result} TRUE PARENT_SCOPE)
+endfunction()
+
+function(CHECK_KO result filename)
+ message("CHECK='${filename}'")
+ set(${result} FALSE PARENT_SCOPE)
+endfunction()
+
+
+find_file(FILE
+ NAMES PrefixInPATH.h
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
+ VALIDATOR check_default
+ )
+message(STATUS "FILE='${FILE}'")
+unset(FILE CACHE)
+
+find_file(FILE
+ NAMES PrefixInPATH.h
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
+ VALIDATOR check_ok
+ )
+message(STATUS "FILE='${FILE}'")
+unset(FILE CACHE)
+
+find_file(FILE
+ NAMES PrefixInPATH.h
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
+ VALIDATOR check_ko
+ )
+message(STATUS "FILE='${FILE}'")
+unset(FILE CACHE)
diff --git a/Tests/RunCMake/find_library/RunCMakeTest.cmake b/Tests/RunCMake/find_library/RunCMakeTest.cmake
index a912077..8b223b4 100644
--- a/Tests/RunCMake/find_library/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_library/RunCMakeTest.cmake
@@ -15,6 +15,10 @@ run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
+run_cmake(VALIDATOR-no-function)
+run_cmake(VALIDATOR-undefined-function)
+run_cmake(VALIDATOR-specify-macro)
+run_cmake(VALIDATOR)
run_cmake_script(FromScriptMode "-DTEMP_DIR=${RunCMake_BINARY_DIR}/FromScriptMode-temp")
diff --git a/Tests/RunCMake/find_library/VALIDATOR-no-function-result.txt b/Tests/RunCMake/find_library/VALIDATOR-no-function-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-no-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_library/VALIDATOR-no-function-stderr.txt b/Tests/RunCMake/find_library/VALIDATOR-no-function-stderr.txt
new file mode 100644
index 0000000..6c04aa4
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-no-function-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_library\):
+ find_library missing required argument for "VALIDATOR"
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/VALIDATOR-no-function.cmake b/Tests/RunCMake/find_library/VALIDATOR-no-function.cmake
new file mode 100644
index 0000000..516e54e
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-no-function.cmake
@@ -0,0 +1,2 @@
+
+find_library(result NAMES input.txt VALIDATOR)
diff --git a/Tests/RunCMake/find_library/VALIDATOR-specify-macro-result.txt b/Tests/RunCMake/find_library/VALIDATOR-specify-macro-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-specify-macro-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_library/VALIDATOR-specify-macro-stderr.txt b/Tests/RunCMake/find_library/VALIDATOR-specify-macro-stderr.txt
new file mode 100644
index 0000000..03e7df9
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-specify-macro-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_library\):
+ find_library command specified for "VALIDATOR" is not a function: check.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/VALIDATOR-specify-macro.cmake b/Tests/RunCMake/find_library/VALIDATOR-specify-macro.cmake
new file mode 100644
index 0000000..fa90d72
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-specify-macro.cmake
@@ -0,0 +1,5 @@
+
+macro(CHECK result path)
+endmacro()
+
+find_library(result NAMES input.txt VALIDATOR check)
diff --git a/Tests/RunCMake/find_library/VALIDATOR-stderr.txt b/Tests/RunCMake/find_library/VALIDATOR-stderr.txt
new file mode 100644
index 0000000..7211450
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-stderr.txt
@@ -0,0 +1,3 @@
+CHECK='[^']+/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
+CHECK='[^']+/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
+CHECK='[^']+/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
diff --git a/Tests/RunCMake/find_library/VALIDATOR-stdout.txt b/Tests/RunCMake/find_library/VALIDATOR-stdout.txt
new file mode 100644
index 0000000..bd2549b
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-stdout.txt
@@ -0,0 +1,3 @@
+-- LIB='[^']+/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
+-- LIB='[^']+/Tests/RunCMake/find_library/lib/libPrefixInPATH.a'
+-- LIB='LIB-NOTFOUND'
diff --git a/Tests/RunCMake/find_library/VALIDATOR-undefined-function-result.txt b/Tests/RunCMake/find_library/VALIDATOR-undefined-function-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-undefined-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_library/VALIDATOR-undefined-function-stderr.txt b/Tests/RunCMake/find_library/VALIDATOR-undefined-function-stderr.txt
new file mode 100644
index 0000000..dc7ad9e
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-undefined-function-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_library\):
+ find_library command specified for "VALIDATOR" is undefined: undefined.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_library/VALIDATOR-undefined-function.cmake b/Tests/RunCMake/find_library/VALIDATOR-undefined-function.cmake
new file mode 100644
index 0000000..9ac7ee0
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR-undefined-function.cmake
@@ -0,0 +1,2 @@
+
+find_library(result NAMES input.txt VALIDATOR undefined)
diff --git a/Tests/RunCMake/find_library/VALIDATOR.cmake b/Tests/RunCMake/find_library/VALIDATOR.cmake
new file mode 100644
index 0000000..7593941
--- /dev/null
+++ b/Tests/RunCMake/find_library/VALIDATOR.cmake
@@ -0,0 +1,41 @@
+list(APPEND CMAKE_FIND_LIBRARY_PREFIXES lib)
+list(APPEND CMAKE_FIND_LIBRARY_SUFFIXES .a)
+
+function(CHECK_DEFAULT result filename)
+ message("CHECK='${filename}'")
+endfunction()
+
+function(CHECK_OK result filename)
+ message("CHECK='${filename}'")
+ set(${result} TRUE PARENT_SCOPE)
+endfunction()
+
+function(CHECK_KO result filename)
+ message("CHECK='${filename}'")
+ set(${result} FALSE PARENT_SCOPE)
+endfunction()
+
+
+find_library(LIB
+ NAMES PrefixInPATH
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/lib
+ VALIDATOR check_default
+ )
+message(STATUS "LIB='${LIB}'")
+unset(LIB CACHE)
+
+find_library(LIB
+ NAMES PrefixInPATH
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/lib
+ VALIDATOR check_ok
+ )
+message(STATUS "LIB='${LIB}'")
+unset(LIB CACHE)
+
+find_library(LIB
+ NAMES PrefixInPATH
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/lib
+ VALIDATOR check_ko
+ )
+message(STATUS "LIB='${LIB}'")
+unset(LIB CACHE)
diff --git a/Tests/RunCMake/find_package/RunCMakeTest.cmake b/Tests/RunCMake/find_package/RunCMakeTest.cmake
index 32e54d5..fa41fc1 100644
--- a/Tests/RunCMake/find_package/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_package/RunCMakeTest.cmake
@@ -55,6 +55,22 @@ run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
run_cmake(REGISTRY_VIEW-propagated)
+file(
+ GLOB SearchPaths_TEST_CASE_LIST
+ LIST_DIRECTORIES TRUE
+ "${RunCMake_SOURCE_DIR}/SearchPaths/*"
+ )
+foreach(TestCasePrefix IN LISTS SearchPaths_TEST_CASE_LIST)
+ if(IS_DIRECTORY "${TestCasePrefix}")
+ cmake_path(GET TestCasePrefix FILENAME TestSuffix)
+ run_cmake_with_options(
+ SearchPaths_${TestSuffix}
+ "-DSearchPaths_ROOT=${TestCasePrefix}"
+ "--debug-find-pkg=SearchPaths"
+ )
+ endif()
+endforeach()
+
if(UNIX
AND NOT MSYS # FIXME: This works on CYGWIN but not on MSYS
)
diff --git a/Tests/RunCMake/find_package/SearchPaths.cmake b/Tests/RunCMake/find_package/SearchPaths.cmake
new file mode 100644
index 0000000..a5a10fc
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths.cmake
@@ -0,0 +1,2 @@
+cmake_policy(SET CMP0074 NEW)
+find_package(SearchPaths REQUIRED CONFIG)
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPaths-1.2.3/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPaths-1.2.3/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPaths-1.2.3/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1.2.3/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1.2.3/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1.2.3/lib/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1.2.3/lib/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1.2.3/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1.2.3/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1.2.3/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1.2.3/share/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1.2.3/share/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1.2.3/share/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1.2.3/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1.2.3/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1.2.3/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1.2.3/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1.2.3/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1.2.3/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake b/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1.2.3/cmake/SearchPathsConfig.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix-stderr.txt
new file mode 100644
index 0000000..fae13ef
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix-stderr.txt
@@ -0,0 +1,10 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-stderr.txt
new file mode 100644
index 0000000..eba88c9
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_cmake/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..cebc169
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_cmake_pkg/lib/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-stderr.txt
new file mode 100644
index 0000000..4e5d3f6
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg/lib/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..f290545
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_lib_pkg_cmake/lib/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_lib_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-stderr.txt
new file mode 100644
index 0000000..32b9fcb
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..7bf5cf8
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..812c607
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPaths-1\.2\.3/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_cmake_pkg/SearchPaths-1\.2\.3/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..3592f72
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1\.2\.3/lib/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_cmake_pkg/SearchPaths-1\.2\.3/lib/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-stderr.txt
new file mode 100644
index 0000000..b196b7a
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1\.2\.3/lib/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg/SearchPaths-1\.2\.3/lib/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..17e0399
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1\.2\.3/lib/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_lib_pkg_cmake/SearchPaths-1\.2\.3/lib/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_lib_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..ee01a50
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1\.2\.3/share/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_cmake_pkg/SearchPaths-1\.2\.3/share/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-stderr.txt
new file mode 100644
index 0000000..d6abd2f
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1\.2\.3/share/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg/SearchPaths-1\.2\.3/share/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..b578b2b
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-stderr.txt
@@ -0,0 +1,14 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1\.2\.3/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1\.2\.3/share/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_pkg_share_pkg_cmake/SearchPaths-1\.2\.3/share/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_pkg_share_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-stderr.txt
new file mode 100644
index 0000000..2f3f18a
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_cmake_pkg/share/cmake/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_cmake_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-stderr.txt
new file mode 100644
index 0000000..3eef002
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg/share/SearchPaths-1\.2\.3/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-stderr.txt b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-stderr.txt
new file mode 100644
index 0000000..c962f8b
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-stderr.txt
@@ -0,0 +1,12 @@
+ find_package considered the following locations for SearchPaths's Config
+ module:
+
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-build/CMakeFiles/pkgRedirects/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake-build/CMakeFiles/pkgRedirects/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/SearchPathsConfig\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/searchpaths-config\.cmake
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
+
+ The file was found at
+
+ .*/Tests/RunCMake/find_package/SearchPaths/prefix_share_pkg_cmake/share/SearchPaths-1\.2\.3/cmake/SearchPathsConfig\.cmake
diff --git a/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake.cmake b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake.cmake
new file mode 100644
index 0000000..d831313
--- /dev/null
+++ b/Tests/RunCMake/find_package/SearchPaths_prefix_share_pkg_cmake.cmake
@@ -0,0 +1 @@
+include("${CMAKE_CURRENT_SOURCE_DIR}/SearchPaths.cmake")
diff --git a/Tests/RunCMake/find_path/RunCMakeTest.cmake b/Tests/RunCMake/find_path/RunCMakeTest.cmake
index 63cadc2..9c76f2e 100644
--- a/Tests/RunCMake/find_path/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_path/RunCMakeTest.cmake
@@ -7,6 +7,10 @@ run_cmake(Required)
run_cmake(NO_CACHE)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
+run_cmake(VALIDATOR-no-function)
+run_cmake(VALIDATOR-undefined-function)
+run_cmake(VALIDATOR-specify-macro)
+run_cmake(VALIDATOR)
if(APPLE)
run_cmake(FrameworksWithSubdirs)
diff --git a/Tests/RunCMake/find_path/VALIDATOR-no-function-result.txt b/Tests/RunCMake/find_path/VALIDATOR-no-function-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-no-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_path/VALIDATOR-no-function-stderr.txt b/Tests/RunCMake/find_path/VALIDATOR-no-function-stderr.txt
new file mode 100644
index 0000000..1dfd064
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-no-function-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_path\):
+ find_path missing required argument for "VALIDATOR"
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_path/VALIDATOR-no-function.cmake b/Tests/RunCMake/find_path/VALIDATOR-no-function.cmake
new file mode 100644
index 0000000..bac2752
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-no-function.cmake
@@ -0,0 +1,2 @@
+
+find_path(result NAMES input.txt VALIDATOR)
diff --git a/Tests/RunCMake/find_path/VALIDATOR-specify-macro-result.txt b/Tests/RunCMake/find_path/VALIDATOR-specify-macro-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-specify-macro-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_path/VALIDATOR-specify-macro-stderr.txt b/Tests/RunCMake/find_path/VALIDATOR-specify-macro-stderr.txt
new file mode 100644
index 0000000..92ee17e
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-specify-macro-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_path\):
+ find_path command specified for "VALIDATOR" is not a function: check.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_path/VALIDATOR-specify-macro.cmake b/Tests/RunCMake/find_path/VALIDATOR-specify-macro.cmake
new file mode 100644
index 0000000..62b44ed
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-specify-macro.cmake
@@ -0,0 +1,5 @@
+
+macro(CHECK result path)
+endmacro()
+
+find_path(result NAMES input.txt VALIDATOR check)
diff --git a/Tests/RunCMake/find_path/VALIDATOR-stderr.txt b/Tests/RunCMake/find_path/VALIDATOR-stderr.txt
new file mode 100644
index 0000000..851353d
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-stderr.txt
@@ -0,0 +1,3 @@
+CHECK='[^']+/Tests/RunCMake/find_path/include/'
+CHECK='[^']+/Tests/RunCMake/find_path/include/'
+CHECK='[^']+/Tests/RunCMake/find_path/include/'
diff --git a/Tests/RunCMake/find_path/VALIDATOR-stdout.txt b/Tests/RunCMake/find_path/VALIDATOR-stdout.txt
new file mode 100644
index 0000000..3fce030
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-stdout.txt
@@ -0,0 +1,3 @@
+-- DIR='[^']+/Tests/RunCMake/find_path/include'
+-- DIR='[^']+/Tests/RunCMake/find_path/include'
+-- DIR='DIR-NOTFOUND'
diff --git a/Tests/RunCMake/find_path/VALIDATOR-undefined-function-result.txt b/Tests/RunCMake/find_path/VALIDATOR-undefined-function-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-undefined-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_path/VALIDATOR-undefined-function-stderr.txt b/Tests/RunCMake/find_path/VALIDATOR-undefined-function-stderr.txt
new file mode 100644
index 0000000..d3e0517
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-undefined-function-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_path\):
+ find_path command specified for "VALIDATOR" is undefined: undefined.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_path/VALIDATOR-undefined-function.cmake b/Tests/RunCMake/find_path/VALIDATOR-undefined-function.cmake
new file mode 100644
index 0000000..3fb55c5
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR-undefined-function.cmake
@@ -0,0 +1,2 @@
+
+find_path(result NAMES input.txt VALIDATOR undefined)
diff --git a/Tests/RunCMake/find_path/VALIDATOR.cmake b/Tests/RunCMake/find_path/VALIDATOR.cmake
new file mode 100644
index 0000000..1e01250
--- /dev/null
+++ b/Tests/RunCMake/find_path/VALIDATOR.cmake
@@ -0,0 +1,39 @@
+
+function(CHECK_DEFAULT result filename)
+ message("CHECK='${filename}'")
+endfunction()
+
+function(CHECK_OK result filename)
+ message("CHECK='${filename}'")
+ set(${result} TRUE PARENT_SCOPE)
+endfunction()
+
+function(CHECK_KO result filename)
+ message("CHECK='${filename}'")
+ set(${result} FALSE PARENT_SCOPE)
+endfunction()
+
+
+find_path(DIR
+ NAMES PrefixInPATH.h
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
+ VALIDATOR check_default
+ )
+message(STATUS "DIR='${DIR}'")
+unset(DIR CACHE)
+
+find_path(DIR
+ NAMES PrefixInPATH.h
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
+ VALIDATOR check_ok
+ )
+message(STATUS "DIR='${DIR}'")
+unset(DIR CACHE)
+
+find_path(DIR
+ NAMES PrefixInPATH.h
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/include
+ VALIDATOR check_ko
+ )
+message(STATUS "DIR='${DIR}'")
+unset(DIR CACHE)
diff --git a/Tests/RunCMake/find_program/RunCMakeTest.cmake b/Tests/RunCMake/find_program/RunCMakeTest.cmake
index d0ce8fc..f8ecb8f 100644
--- a/Tests/RunCMake/find_program/RunCMakeTest.cmake
+++ b/Tests/RunCMake/find_program/RunCMakeTest.cmake
@@ -9,6 +9,10 @@ run_cmake(NO_CACHE)
run_cmake(IgnorePrefixPath)
run_cmake(REGISTRY_VIEW-no-view)
run_cmake(REGISTRY_VIEW-wrong-view)
+run_cmake(VALIDATOR-no-function)
+run_cmake(VALIDATOR-undefined-function)
+run_cmake(VALIDATOR-specify-macro)
+run_cmake(VALIDATOR)
if(CMAKE_SYSTEM_NAME MATCHES "^(Windows|CYGWIN|MSYS)$")
run_cmake(WindowsCom)
diff --git a/Tests/RunCMake/find_program/VALIDATOR-no-function-result.txt b/Tests/RunCMake/find_program/VALIDATOR-no-function-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-no-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_program/VALIDATOR-no-function-stderr.txt b/Tests/RunCMake/find_program/VALIDATOR-no-function-stderr.txt
new file mode 100644
index 0000000..b8868af
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-no-function-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-no-function.cmake:[0-9]+ \(find_program\):
+ find_program missing required argument for "VALIDATOR"
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/VALIDATOR-no-function.cmake b/Tests/RunCMake/find_program/VALIDATOR-no-function.cmake
new file mode 100644
index 0000000..0d6a74f
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-no-function.cmake
@@ -0,0 +1,2 @@
+
+find_program(result NAMES input.txt VALIDATOR)
diff --git a/Tests/RunCMake/find_program/VALIDATOR-specify-macro-result.txt b/Tests/RunCMake/find_program/VALIDATOR-specify-macro-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-specify-macro-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_program/VALIDATOR-specify-macro-stderr.txt b/Tests/RunCMake/find_program/VALIDATOR-specify-macro-stderr.txt
new file mode 100644
index 0000000..1ae5148
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-specify-macro-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-specify-macro.cmake:[0-9]+ \(find_program\):
+ find_program command specified for "VALIDATOR" is not a function: check.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/VALIDATOR-specify-macro.cmake b/Tests/RunCMake/find_program/VALIDATOR-specify-macro.cmake
new file mode 100644
index 0000000..43bb9ec
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-specify-macro.cmake
@@ -0,0 +1,5 @@
+
+macro(CHECK result path)
+endmacro()
+
+find_program(result NAMES input.txt VALIDATOR check)
diff --git a/Tests/RunCMake/find_program/VALIDATOR-stderr.txt b/Tests/RunCMake/find_program/VALIDATOR-stderr.txt
new file mode 100644
index 0000000..6704ed1
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-stderr.txt
@@ -0,0 +1,3 @@
+CHECK='[^']+/Tests/RunCMake/find_program/A/testA'
+CHECK='[^']+/Tests/RunCMake/find_program/A/testA'
+CHECK='[^']+/Tests/RunCMake/find_program/A/testA'
diff --git a/Tests/RunCMake/find_program/VALIDATOR-stdout.txt b/Tests/RunCMake/find_program/VALIDATOR-stdout.txt
new file mode 100644
index 0000000..d434742
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-stdout.txt
@@ -0,0 +1,3 @@
+-- PROG='[^']+/Tests/RunCMake/find_program/A/testA'
+-- PROG='[^']+/Tests/RunCMake/find_program/A/testA'
+-- PROG='PROG-NOTFOUND'
diff --git a/Tests/RunCMake/find_program/VALIDATOR-undefined-function-result.txt b/Tests/RunCMake/find_program/VALIDATOR-undefined-function-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-undefined-function-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/find_program/VALIDATOR-undefined-function-stderr.txt b/Tests/RunCMake/find_program/VALIDATOR-undefined-function-stderr.txt
new file mode 100644
index 0000000..a89ffa0
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-undefined-function-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at VALIDATOR-undefined-function.cmake:[0-9]+ \(find_program\):
+ find_program command specified for "VALIDATOR" is undefined: undefined.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/find_program/VALIDATOR-undefined-function.cmake b/Tests/RunCMake/find_program/VALIDATOR-undefined-function.cmake
new file mode 100644
index 0000000..96be5fd
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR-undefined-function.cmake
@@ -0,0 +1,2 @@
+
+find_program(result NAMES input.txt VALIDATOR undefined)
diff --git a/Tests/RunCMake/find_program/VALIDATOR.cmake b/Tests/RunCMake/find_program/VALIDATOR.cmake
new file mode 100644
index 0000000..8be2b39
--- /dev/null
+++ b/Tests/RunCMake/find_program/VALIDATOR.cmake
@@ -0,0 +1,39 @@
+
+function(CHECK_DEFAULT result filename)
+ message("CHECK='${filename}'")
+endfunction()
+
+function(CHECK_OK result filename)
+ message("CHECK='${filename}'")
+ set(${result} TRUE PARENT_SCOPE)
+endfunction()
+
+function(CHECK_KO result filename)
+ message("CHECK='${filename}'")
+ set(${result} FALSE PARENT_SCOPE)
+endfunction()
+
+
+find_program(PROG
+ NAMES testA
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/A
+ VALIDATOR check_default
+ )
+message(STATUS "PROG='${PROG}'")
+unset(PROG CACHE)
+
+find_program(PROG
+ NAMES testA
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/A
+ VALIDATOR check_ok
+ )
+message(STATUS "PROG='${PROG}'")
+unset(PROG CACHE)
+
+find_program(PROG
+ NAMES testA
+ HINTS ${CMAKE_CURRENT_SOURCE_DIR}/A
+ VALIDATOR check_ko
+ )
+message(STATUS "PROG='${PROG}'")
+unset(PROG CACHE)
diff --git a/Tests/RunCMake/project/LanguagesDuplicate-check.cmake b/Tests/RunCMake/project/LanguagesDuplicate-check.cmake
new file mode 100644
index 0000000..31c7da3
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesDuplicate-check.cmake
@@ -0,0 +1,10 @@
+if(NOT actual_stderr MATCHES "The following language has been specified multiple times: C\n")
+ set(RunCMake_TEST_FAILED "'LANGUAGES C C C' should report only 'C' and only once.")
+endif()
+
+if(NOT actual_stderr MATCHES "The following languages have been specified multiple times: C, CXX\n")
+ if(RunCMake_TEST_FAILED)
+ string(APPEND RunCMake_TEST_FAILED "\n")
+ endif()
+ string(APPEND RunCMake_TEST_FAILED "'LANGUAGES C C CXX CXX' should report 'C' and 'CXX'.")
+endif()
diff --git a/Tests/RunCMake/project/LanguagesDuplicate.cmake b/Tests/RunCMake/project/LanguagesDuplicate.cmake
new file mode 100644
index 0000000..97a79d0
--- /dev/null
+++ b/Tests/RunCMake/project/LanguagesDuplicate.cmake
@@ -0,0 +1,11 @@
+cmake_policy(SET CMP0057 NEW)
+
+project(ProjectA C C C)
+project(ProjectB C C CXX CXX)
+
+get_property(langs GLOBAL PROPERTY ENABLED_LANGUAGES)
+foreach(lang C CXX)
+ if(NOT lang IN_LIST langs)
+ message(FATAL_ERROR "Expected language '${lang}' to be enabled.")
+ endif()
+endforeach()
diff --git a/Tests/RunCMake/project/RunCMakeTest.cmake b/Tests/RunCMake/project/RunCMakeTest.cmake
index 945d9ed..6d9f52f 100644
--- a/Tests/RunCMake/project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/project/RunCMakeTest.cmake
@@ -12,6 +12,11 @@ run_cmake_with_options(CodeInjection
if(CMake_TEST_RESOURCES)
run_cmake(ExplicitRC)
endif()
+
+set(RunCMake_DEFAULT_stderr .)
+run_cmake(LanguagesDuplicate)
+unset(RunCMake_DEFAULT_stderr)
+
run_cmake(LanguagesImplicit)
run_cmake(LanguagesEmpty)
run_cmake(LanguagesNONE)
diff --git a/Tests/RunCMake/return/CMP0140-NEW.cmake b/Tests/RunCMake/return/CMP0140-NEW.cmake
new file mode 100644
index 0000000..eb6b85c
--- /dev/null
+++ b/Tests/RunCMake/return/CMP0140-NEW.cmake
@@ -0,0 +1,13 @@
+
+cmake_policy(SET CMP0140 NEW)
+
+function(FUNC)
+ set(VAR "set")
+ return(PROPAGATE VAR)
+endfunction()
+
+set(VAR "initial")
+func()
+if (NOT DEFINED VAR OR NOT VAR STREQUAL "set")
+ message(FATAL_ERROR "return(PROPAGATE) not handled correctly.")
+endif()
diff --git a/Tests/RunCMake/return/CMP0140-OLD.cmake b/Tests/RunCMake/return/CMP0140-OLD.cmake
new file mode 100644
index 0000000..8113a43
--- /dev/null
+++ b/Tests/RunCMake/return/CMP0140-OLD.cmake
@@ -0,0 +1,8 @@
+
+cmake_policy(SET CMP0140 OLD)
+
+function(FUNC)
+ return(PROPAGATE VAR)
+endfunction()
+
+func()
diff --git a/Tests/RunCMake/return/CMP0140-WARN-result.txt b/Tests/RunCMake/return/CMP0140-WARN-result.txt
new file mode 100644
index 0000000..573541a
--- /dev/null
+++ b/Tests/RunCMake/return/CMP0140-WARN-result.txt
@@ -0,0 +1 @@
+0
diff --git a/Tests/RunCMake/return/CMP0140-WARN-stderr.txt b/Tests/RunCMake/return/CMP0140-WARN-stderr.txt
new file mode 100644
index 0000000..ed4beb6
--- /dev/null
+++ b/Tests/RunCMake/return/CMP0140-WARN-stderr.txt
@@ -0,0 +1,12 @@
+CMake Warning \(dev\) at CMP0140-WARN.cmake:[0-9]+ \(return\):
+ Policy CMP0140 is not set: The return\(\) command checks its arguments. Run
+ "cmake --help-policy CMP0140" for policy details. Use the cmake_policy
+ command to set the policy and suppress this warning.
+
+ return\(\) checks its arguments when the policy is set to NEW. Since the
+ policy is not set the OLD behavior will be used so the arguments will be
+ ignored.
+Call Stack \(most recent call first\):
+ CMP0140-WARN.cmake:[0-9]+ \(func\)
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
diff --git a/Tests/RunCMake/return/CMP0140-WARN.cmake b/Tests/RunCMake/return/CMP0140-WARN.cmake
new file mode 100644
index 0000000..df2fc88
--- /dev/null
+++ b/Tests/RunCMake/return/CMP0140-WARN.cmake
@@ -0,0 +1,8 @@
+
+cmake_policy(VERSION 3.1)
+
+function(FUNC)
+ return(PROPAGATE VAR)
+endfunction()
+
+func()
diff --git a/Tests/RunCMake/return/CMakeLists.txt b/Tests/RunCMake/return/CMakeLists.txt
index ef2163c..6cc903f 100644
--- a/Tests/RunCMake/return/CMakeLists.txt
+++ b/Tests/RunCMake/return/CMakeLists.txt
@@ -1,3 +1,3 @@
-cmake_minimum_required(VERSION 3.1)
+cmake_minimum_required(VERSION 3.1...3.25)
project(${RunCMake_TEST} NONE)
include(${RunCMake_TEST}.cmake)
diff --git a/Tests/RunCMake/return/PropagateFromDirectory.cmake b/Tests/RunCMake/return/PropagateFromDirectory.cmake
new file mode 100644
index 0000000..9c820bb
--- /dev/null
+++ b/Tests/RunCMake/return/PropagateFromDirectory.cmake
@@ -0,0 +1,10 @@
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+
+add_subdirectory(subdir)
+
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for FUNC1")
+endif()
diff --git a/Tests/RunCMake/return/PropagateFromFunction.cmake b/Tests/RunCMake/return/PropagateFromFunction.cmake
new file mode 100644
index 0000000..1c12bc1
--- /dev/null
+++ b/Tests/RunCMake/return/PropagateFromFunction.cmake
@@ -0,0 +1,142 @@
+
+function(FUNC1)
+ set(VAR1 "set")
+ unset(VAR2)
+ return(PROPAGATE VAR1 VAR2)
+endfunction()
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+func1()
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for FUNC1")
+endif()
+
+
+function(FUNC2)
+ block()
+ set(VAR1 "set")
+ unset(VAR2)
+ return(PROPAGATE VAR1 VAR2)
+ endblock()
+endfunction()
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+func2()
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for FUNC2")
+endif()
+
+
+function(FUNC3)
+ block(SCOPE_FOR POLICIES)
+ set(VAR1 "set")
+ unset(VAR2)
+ return(PROPAGATE VAR1 VAR2)
+ endblock()
+endfunction()
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+func3()
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for FUNC3")
+endif()
+
+
+function(FUNC4)
+ while(TRUE)
+ set(VAR1 "set")
+ unset(VAR2)
+ return(PROPAGATE VAR1 VAR2)
+ endwhile()
+endfunction()
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+func4()
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for FUNC4")
+endif()
+
+
+function(FUNC5)
+ foreach(item IN ITEMS A B)
+ set(VAR1 "set")
+ unset(VAR2)
+ return(PROPAGATE VAR1 VAR2)
+ endforeach()
+endfunction()
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+func5()
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for FUNC5")
+endif()
+
+
+function(FUNC6)
+ if(TRUE)
+ set(VAR1 "set")
+ unset(VAR2)
+ return(PROPAGATE VAR1 VAR2)
+ endif()
+endfunction()
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+func6()
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for FUNC6")
+endif()
+
+
+function(FUNC7)
+ if(FALSE)
+ else()
+ set(VAR1 "set")
+ unset(VAR2)
+ return(PROPAGATE VAR1 VAR2)
+ endif()
+endfunction()
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+func7()
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for FUNC7")
+endif()
+
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+cmake_language(CALL func7)
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for cmake_language(CALL FUNC7)")
+endif()
+
+
+set(VAR1 "initial")
+set(VAR2 "initial")
+cmake_language(EVAL CODE "
+ function(FUNC8)
+ set(VAR1 \"set\")
+ unset(VAR2)
+ return(PROPAGATE VAR1 VAR2)
+ endfunction()
+
+ func8()")
+if((NOT DEFINED VAR1 OR NOT VAR1 STREQUAL "set")
+ OR DEFINED VAR2)
+ message(SEND_ERROR "erroneous propagation for cmake_language(EVAL CODE)")
+endif()
diff --git a/Tests/RunCMake/return/PropagateNothing.cmake b/Tests/RunCMake/return/PropagateNothing.cmake
new file mode 100644
index 0000000..0ace58e
--- /dev/null
+++ b/Tests/RunCMake/return/PropagateNothing.cmake
@@ -0,0 +1,2 @@
+
+return(PROPAGATE)
diff --git a/Tests/RunCMake/return/RunCMakeTest.cmake b/Tests/RunCMake/return/RunCMakeTest.cmake
index 2cc6c9d..f9e06a5 100644
--- a/Tests/RunCMake/return/RunCMakeTest.cmake
+++ b/Tests/RunCMake/return/RunCMakeTest.cmake
@@ -1,3 +1,12 @@
include(RunCMake)
run_cmake(ReturnFromForeach)
+
+run_cmake(WrongArgument)
+run_cmake(PropagateNothing)
+run_cmake(PropagateFromFunction)
+run_cmake(PropagateFromDirectory)
+
+run_cmake(CMP0140-NEW)
+run_cmake(CMP0140-OLD)
+run_cmake(CMP0140-WARN)
diff --git a/Tests/RunCMake/return/WrongArgument-result.txt b/Tests/RunCMake/return/WrongArgument-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/return/WrongArgument-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/return/WrongArgument-stderr.txt b/Tests/RunCMake/return/WrongArgument-stderr.txt
new file mode 100644
index 0000000..4d1c5ad
--- /dev/null
+++ b/Tests/RunCMake/return/WrongArgument-stderr.txt
@@ -0,0 +1,4 @@
+CMake Error at WrongArgument.cmake:[0-9]+ \(return\):
+ return called with unsupported argument "WRONG_ARG"
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/return/WrongArgument.cmake b/Tests/RunCMake/return/WrongArgument.cmake
new file mode 100644
index 0000000..d03b19f
--- /dev/null
+++ b/Tests/RunCMake/return/WrongArgument.cmake
@@ -0,0 +1,2 @@
+
+return(WRONG_ARG)
diff --git a/Tests/RunCMake/return/subdir/CMakeLists.txt b/Tests/RunCMake/return/subdir/CMakeLists.txt
new file mode 100644
index 0000000..e575d47
--- /dev/null
+++ b/Tests/RunCMake/return/subdir/CMakeLists.txt
@@ -0,0 +1,5 @@
+
+set(VAR1 "set")
+unset(VAR2)
+
+return(PROPAGATE VAR1 VAR2)
diff --git a/Tests/RunCMake/string/JSON.cmake b/Tests/RunCMake/string/JSON.cmake
index ab4194d..255c16a 100644
--- a/Tests/RunCMake/string/JSON.cmake
+++ b/Tests/RunCMake/string/JSON.cmake
@@ -129,7 +129,7 @@ assert_strequal("${error}" "member '0' not found")
string(JSON result ERROR_VARIABLE error GET "${json1}" array 10)
assert_strequal("${result}" "array-10-NOTFOUND")
-assert_strequal("${error}" "expected an index less then 4 got '10'")
+assert_strequal("${error}" "expected an index less than 4 got '10'")
string(JSON result ERROR_VARIABLE error GET "${json1}" array 2 some notThere)
assert_strequal("${result}" "array-2-some-notThere-NOTFOUND")
@@ -240,7 +240,7 @@ endif()
string(JSON result ERROR_VARIABLE error MEMBER "${json1}" values 100)
assert_strequal("${result}" "values-100-NOTFOUND")
-assert_strequal("${error}" "expected an index less then 5 got '100'")
+assert_strequal("${error}" "expected an index less than 5 got '100'")
# Test length loops
string(JSON arrayLength ERROR_VARIABLE error LENGTH "${json1}" types array)
@@ -301,7 +301,7 @@ assert_json_equal("${error}" "${result}"
string(JSON result ERROR_VARIABLE error REMOVE ${json2} array 100)
assert_strequal("${result}" "array-100-NOTFOUND")
-assert_strequal("${error}" "expected an index less then 4 got '100'")
+assert_strequal("${error}" "expected an index less than 4 got '100'")
# Test SET
string(JSON result ERROR_VARIABLE error SET ${json2} new 5)
diff --git a/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-stderr.txt b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-stderr.txt
new file mode 100644
index 0000000..f04e43f
--- /dev/null
+++ b/Tests/RunCMake/target_compile_options/CMP0101-BEFORE_keyword-stderr.txt
@@ -0,0 +1,10 @@
+^CMake Deprecation Warning at CMP0101-BEFORE_keyword.cmake:[0-9]+ \(cmake_policy\):
+ The OLD behavior for policy CMP0101 will be removed from a future version
+ of CMake.
+
+ The cmake-policies\(7\) manual explains that the OLD behaviors of all
+ policies are deprecated and that a policy should be set to OLD only under
+ specific short-term circumstances. Projects should be ported to the NEW
+ behavior and not rely on setting a policy to OLD.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental-result.txt b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental-stderr.txt b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental-stderr.txt
new file mode 100644
index 0000000..042d67d
--- /dev/null
+++ b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(dev\) at FileSetDefaultWrongTypeExperimental.cmake:6 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at FileSetDefaultWrongTypeExperimental\.cmake:[0-9]+ \(target_sources\):
+ target_sources File set TYPE may only be "HEADERS", "CXX_MODULES", or
+ "CXX_MODULE_HEADER_UNITS"
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake
new file mode 100644
index 0000000..5ade637
--- /dev/null
+++ b/Tests/RunCMake/target_sources/FileSetDefaultWrongTypeExperimental.cmake
@@ -0,0 +1,6 @@
+enable_language(C)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
+
+add_library(lib1 STATIC empty.c)
+target_sources(lib1 PRIVATE FILE_SET UNKNOWN)
diff --git a/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental-result.txt b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental-stderr.txt b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental-stderr.txt
new file mode 100644
index 0000000..a1b784f
--- /dev/null
+++ b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental-stderr.txt
@@ -0,0 +1,12 @@
+^CMake Warning \(dev\) at FileSetWrongTypeExperimental.cmake:6 \(target_sources\):
+ CMake's C\+\+ module support is experimental. It is meant only for
+ experimentation and feedback to CMake developers.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.
+
+CMake Error at FileSetWrongTypeExperimental\.cmake:[0-9]+ \(target_sources\):
+ target_sources File set TYPE may only be "HEADERS", "CXX_MODULES", or
+ "CXX_MODULE_HEADER_UNITS"
+Call Stack \(most recent call first\):
+ CMakeLists\.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake
new file mode 100644
index 0000000..332441c
--- /dev/null
+++ b/Tests/RunCMake/target_sources/FileSetWrongTypeExperimental.cmake
@@ -0,0 +1,6 @@
+enable_language(C)
+
+set(CMAKE_EXPERIMENTAL_CXX_MODULE_CMAKE_API "3c375311-a3c9-4396-a187-3227ef642046")
+
+add_library(lib1 STATIC empty.c)
+target_sources(lib1 PRIVATE FILE_SET a TYPE UNKNOWN)
diff --git a/Tests/RunCMake/target_sources/RunCMakeTest.cmake b/Tests/RunCMake/target_sources/RunCMakeTest.cmake
index 6a3c7b9..7c67c3f 100644
--- a/Tests/RunCMake/target_sources/RunCMakeTest.cmake
+++ b/Tests/RunCMake/target_sources/RunCMakeTest.cmake
@@ -26,6 +26,8 @@ run_cmake(FileSetProperties)
run_cmake(FileSetNoType)
run_cmake(FileSetWrongType)
run_cmake(FileSetDefaultWrongType)
+run_cmake(FileSetWrongTypeExperimental)
+run_cmake(FileSetDefaultWrongTypeExperimental)
run_cmake(FileSetChangeScope)
run_cmake(FileSetChangeType)
run_cmake(FileSetWrongBaseDirs)
diff --git a/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt b/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt
index 652bcfc..4e41a19 100644
--- a/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt
+++ b/Tests/RunCMake/try_compile/BadLinkLibraries-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at BadLinkLibraries.cmake:2 \(try_compile\):
+CMake Error at BadLinkLibraries.cmake:[0-9]+ \(try_compile\):
Only libraries may be used as try_compile or try_run IMPORTED
LINK_LIBRARIES. Got not_a_library of type UTILITY.
Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/try_compile/BadLinkLibraries.cmake b/Tests/RunCMake/try_compile/BadLinkLibraries.cmake
index e8b5add..b758e23 100644
--- a/Tests/RunCMake/try_compile/BadLinkLibraries.cmake
+++ b/Tests/RunCMake/try_compile/BadLinkLibraries.cmake
@@ -1,3 +1,7 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
add_custom_target(not_a_library)
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
LINK_LIBRARIES not_a_library)
diff --git a/Tests/RunCMake/try_compile/BadSources1-stderr.txt b/Tests/RunCMake/try_compile/BadSources1-stderr.txt
index 864a294..ddcba4f 100644
--- a/Tests/RunCMake/try_compile/BadSources1-stderr.txt
+++ b/Tests/RunCMake/try_compile/BadSources1-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at BadSources1.cmake:1 \(try_compile\):
+CMake Error at BadSources1.cmake:[0-9]+ \(try_compile\):
Unknown extension ".c" for file
.*/Tests/RunCMake/try_compile/src.c
diff --git a/Tests/RunCMake/try_compile/BadSources1.cmake b/Tests/RunCMake/try_compile/BadSources1.cmake
index aa4dc5e..c95935d 100644
--- a/Tests/RunCMake/try_compile/BadSources1.cmake
+++ b/Tests/RunCMake/try_compile/BadSources1.cmake
@@ -1 +1,3 @@
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
diff --git a/Tests/RunCMake/try_compile/BadSources2-stderr.txt b/Tests/RunCMake/try_compile/BadSources2-stderr.txt
index 3313f99..953dd9c 100644
--- a/Tests/RunCMake/try_compile/BadSources2-stderr.txt
+++ b/Tests/RunCMake/try_compile/BadSources2-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at BadSources2.cmake:2 \(try_compile\):
+CMake Error at BadSources2.cmake:[0-9]+ \(try_compile\):
Unknown extension ".cxx" for file
.*/Tests/RunCMake/try_compile/src.cxx
diff --git a/Tests/RunCMake/try_compile/BadSources2.cmake b/Tests/RunCMake/try_compile/BadSources2.cmake
index ed2b036..3f22bb6 100644
--- a/Tests/RunCMake/try_compile/BadSources2.cmake
+++ b/Tests/RunCMake/try_compile/BadSources2.cmake
@@ -1,5 +1,6 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
enable_language(C)
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
- ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
)
diff --git a/Tests/RunCMake/try_compile/BinDirEmpty-result.txt b/Tests/RunCMake/try_compile/BinDirEmpty-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_compile/BinDirEmpty-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_compile/BinDirEmpty-stderr.txt b/Tests/RunCMake/try_compile/BinDirEmpty-stderr.txt
new file mode 100644
index 0000000..b1f5ae3
--- /dev/null
+++ b/Tests/RunCMake/try_compile/BinDirEmpty-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at BinDirEmpty.cmake:[0-9]+ \(try_compile\):
+ No <bindir> specified.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_compile/BinDirEmpty.cmake b/Tests/RunCMake/try_compile/BinDirEmpty.cmake
new file mode 100644
index 0000000..7bea43d
--- /dev/null
+++ b/Tests/RunCMake/try_compile/BinDirEmpty.cmake
@@ -0,0 +1 @@
+try_compile(resultVar "" ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
diff --git a/Tests/RunCMake/try_compile/BinDirRelative-result.txt b/Tests/RunCMake/try_compile/BinDirRelative-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_compile/BinDirRelative-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_compile/BinDirRelative-stderr.txt b/Tests/RunCMake/try_compile/BinDirRelative-stderr.txt
new file mode 100644
index 0000000..a7b6302
--- /dev/null
+++ b/Tests/RunCMake/try_compile/BinDirRelative-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at BinDirRelative.cmake:[0-9]+ \(try_compile\):
+ <bindir> is not an absolute path:
+
+ 'bin_dir_relative'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_compile/BinDirRelative.cmake b/Tests/RunCMake/try_compile/BinDirRelative.cmake
new file mode 100644
index 0000000..8deda11
--- /dev/null
+++ b/Tests/RunCMake/try_compile/BinDirRelative.cmake
@@ -0,0 +1 @@
+try_compile(resultVar bin_dir_relative ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
diff --git a/Tests/RunCMake/try_compile/CStandard-stderr.txt b/Tests/RunCMake/try_compile/CStandard-stderr.txt
index 209afcc..c3c48a1 100644
--- a/Tests/RunCMake/try_compile/CStandard-stderr.txt
+++ b/Tests/RunCMake/try_compile/CStandard-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at .*/Tests/RunCMake/try_compile/CStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+^CMake Error at .*/Tests/RunCMake/try_compile/CStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists.txt:[0-9]+ \(add_executable\):
C_STANDARD is set to invalid value '3'
+
CMake Error at CStandard.cmake:[0-9]+ \(try_compile\):
diff --git a/Tests/RunCMake/try_compile/CStandard.cmake b/Tests/RunCMake/try_compile/CStandard.cmake
index 2849ed4..6ac04db 100644
--- a/Tests/RunCMake/try_compile/CStandard.cmake
+++ b/Tests/RunCMake/try_compile/CStandard.cmake
@@ -1,7 +1,11 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(C)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
C_STANDARD 3
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/CStandardGNU.cmake b/Tests/RunCMake/try_compile/CStandardGNU.cmake
index 79ae874..10a4384 100644
--- a/Tests/RunCMake/try_compile/CStandardGNU.cmake
+++ b/Tests/RunCMake/try_compile/CStandardGNU.cmake
@@ -1,23 +1,30 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(C)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CStandardGNU.c
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/CStandardGNU.c
C_STANDARD 99
C_STANDARD_REQUIRED 1
C_EXTENSIONS 0
OUTPUT_VARIABLE out
)
+
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
cmake_policy(SET CMP0067 NEW)
+
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED 1)
set(CMAKE_C_EXTENSIONS 0)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CStandardGNU.c
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/CStandardGNU.c
OUTPUT_VARIABLE out
)
+
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
diff --git a/Tests/RunCMake/try_compile/CStandardNoDefault.cmake b/Tests/RunCMake/try_compile/CStandardNoDefault.cmake
index 97e72ea..f4dd5ae 100644
--- a/Tests/RunCMake/try_compile/CStandardNoDefault.cmake
+++ b/Tests/RunCMake/try_compile/CStandardNoDefault.cmake
@@ -1,9 +1,13 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(C)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
C_STANDARD 3 # bogus, but not used
OUTPUT_VARIABLE out
)
+
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
diff --git a/Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile-stderr.txt b/Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile-stderr.txt
index 5d09c0c..8c49302 100644
--- a/Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile-stderr.txt
+++ b/Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at CopyFileErrorNoCopyFile.cmake:1 \(try_compile\):
+CMake Error at CopyFileErrorNoCopyFile.cmake:[0-9]+ \(try_compile\):
COPY_FILE_ERROR may be used only with COPY_FILE
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile.cmake b/Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile.cmake
index 8d7cb0e..8d15b3d 100644
--- a/Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile.cmake
+++ b/Tests/RunCMake/try_compile/CopyFileErrorNoCopyFile.cmake
@@ -1,2 +1,4 @@
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
COPY_FILE_ERROR _copied)
diff --git a/Tests/RunCMake/try_compile/CudaStandard-stderr.txt b/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
index bcf95d5..52dff8f 100644
--- a/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
+++ b/Tests/RunCMake/try_compile/CudaStandard-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at .*/Tests/RunCMake/try_compile/CudaStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+^CMake Error at .*/Tests/RunCMake/try_compile/CudaStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists.txt:[0-9]+ \(add_executable\):
CUDA_STANDARD is set to invalid value '4'
+
CMake Error at CudaStandard.cmake:[0-9]+ \(try_compile\):
diff --git a/Tests/RunCMake/try_compile/CudaStandard.cmake b/Tests/RunCMake/try_compile/CudaStandard.cmake
index a230424..0be89be 100644
--- a/Tests/RunCMake/try_compile/CudaStandard.cmake
+++ b/Tests/RunCMake/try_compile/CudaStandard.cmake
@@ -1,7 +1,11 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(CUDA)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cu
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.cu
CUDA_STANDARD 4
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/CxxStandard-stderr.txt b/Tests/RunCMake/try_compile/CxxStandard-stderr.txt
index ec7245f..55a06e2 100644
--- a/Tests/RunCMake/try_compile/CxxStandard-stderr.txt
+++ b/Tests/RunCMake/try_compile/CxxStandard-stderr.txt
@@ -1,6 +1,17 @@
-^CMake Error at .*/Tests/RunCMake/try_compile/CxxStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+^(CMake Error in .*/Tests/RunCMake/try_compile/CxxStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists.txt:
+ The CXX_STANDARD property on target "cmTC_[0-9a-f]*" contained an invalid
+ value: "3".
+
+
+)?CMake Error at .*/Tests/RunCMake/try_compile/CxxStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists.txt:[0-9]+ \(add_executable\):
CXX_STANDARD is set to invalid value '3'
-+
+
+(
+CMake Error in .*/Tests/RunCMake/try_compile/CxxStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists.txt:
+ The CXX_STANDARD property on target "cmTC_[0-9a-f]*" contained an invalid
+ value: "3".
+
+)?
CMake Error at CxxStandard.cmake:[0-9]+ \(try_compile\):
Failed to generate test project build system.
Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/try_compile/CxxStandard.cmake b/Tests/RunCMake/try_compile/CxxStandard.cmake
index bcb49b9..e5b4e78 100644
--- a/Tests/RunCMake/try_compile/CxxStandard.cmake
+++ b/Tests/RunCMake/try_compile/CxxStandard.cmake
@@ -1,7 +1,11 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(CXX)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
CXX_STANDARD 3
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/CxxStandardGNU.cmake b/Tests/RunCMake/try_compile/CxxStandardGNU.cmake
index e714fe4..552d99d 100644
--- a/Tests/RunCMake/try_compile/CxxStandardGNU.cmake
+++ b/Tests/RunCMake/try_compile/CxxStandardGNU.cmake
@@ -1,23 +1,30 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(CXX)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CxxStandardGNU.cxx
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/CxxStandardGNU.cxx
CXX_STANDARD 11
CXX_STANDARD_REQUIRED 1
CXX_EXTENSIONS 0
OUTPUT_VARIABLE out
)
+
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
cmake_policy(SET CMP0067 NEW)
+
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED 1)
set(CMAKE_CXX_EXTENSIONS 0)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/CxxStandardGNU.cxx
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/CxxStandardGNU.cxx
OUTPUT_VARIABLE out
)
+
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
diff --git a/Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake b/Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake
index 35caa9d..e0ebfee 100644
--- a/Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake
+++ b/Tests/RunCMake/try_compile/CxxStandardNoDefault.cmake
@@ -1,9 +1,13 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(CXX)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.cxx
CXX_STANDARD 3 # bogus, but not used
OUTPUT_VARIABLE out
)
+
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
diff --git a/Tests/RunCMake/try_compile/EmptyListArgs.cmake b/Tests/RunCMake/try_compile/EmptyListArgs.cmake
new file mode 100644
index 0000000..5cd7465
--- /dev/null
+++ b/Tests/RunCMake/try_compile/EmptyListArgs.cmake
@@ -0,0 +1,11 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
+enable_language(C)
+
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ CMAKE_FLAGS # no values
+ COMPILE_DEFINITIONS # no values
+ LINK_LIBRARIES # no values
+ LINK_OPTIONS # no values
+ )
diff --git a/Tests/RunCMake/try_compile/EmptyValueArgs-result.txt b/Tests/RunCMake/try_compile/EmptyValueArgs-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_compile/EmptyValueArgs-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_compile/EmptyValueArgs-stderr.txt b/Tests/RunCMake/try_compile/EmptyValueArgs-stderr.txt
new file mode 100644
index 0000000..b1344bd
--- /dev/null
+++ b/Tests/RunCMake/try_compile/EmptyValueArgs-stderr.txt
@@ -0,0 +1,9 @@
+CMake Error at EmptyValueArgs.cmake:[0-9]+ \(try_compile\):
+ COPY_FILE must be followed by a file path
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
++
+CMake Error at EmptyValueArgs.cmake:[0-9]+ \(try_compile\):
+ COPY_FILE_ERROR must be followed by a variable name
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
diff --git a/Tests/RunCMake/try_compile/EmptyValueArgs.cmake b/Tests/RunCMake/try_compile/EmptyValueArgs.cmake
new file mode 100644
index 0000000..fda4f10
--- /dev/null
+++ b/Tests/RunCMake/try_compile/EmptyValueArgs.cmake
@@ -0,0 +1,7 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ COPY_FILE "")
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ COPY_FILE "x" COPY_FILE_ERROR "")
diff --git a/Tests/RunCMake/try_compile/EnvConfig.cmake b/Tests/RunCMake/try_compile/EnvConfig.cmake
index 4040c59..6e66825 100644
--- a/Tests/RunCMake/try_compile/EnvConfig.cmake
+++ b/Tests/RunCMake/try_compile/EnvConfig.cmake
@@ -1,3 +1,5 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(C)
set(ENV{CMAKE_BUILD_TYPE} "Bad")
@@ -6,8 +8,8 @@ set(ENV{CMAKE_CONFIGURATION_TYPES} "Bad;Debug")
add_library(tc_defs INTERFACE IMPORTED)
target_compile_definitions(tc_defs INTERFACE "TC_CONFIG_$<UPPER_CASE:$<CONFIG>>")
-try_compile(ENV_CONFIG_RESULT "${CMAKE_BINARY_DIR}"
- SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/EnvConfig.c"
+try_compile(ENV_CONFIG_RESULT "${try_compile_bindir_or_SOURCES}"
+ ${try_compile_redundant_SOURCES} "${CMAKE_CURRENT_SOURCE_DIR}/EnvConfig.c"
COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/EnvConfig.bin"
OUTPUT_VARIABLE tc_output
LINK_LIBRARIES tc_defs
diff --git a/Tests/RunCMake/try_compile/ISPCDuplicateTarget.cmake b/Tests/RunCMake/try_compile/ISPCDuplicateTarget.cmake
index 6d29069..1ead4c2 100644
--- a/Tests/RunCMake/try_compile/ISPCDuplicateTarget.cmake
+++ b/Tests/RunCMake/try_compile/ISPCDuplicateTarget.cmake
@@ -1,8 +1,12 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(ISPC)
-set(CMAKE_ISPC_INSTRUCTION_SETS avx512skx-i32x16
- avx512skx-i32x16)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.ispc
+
+set(CMAKE_ISPC_INSTRUCTION_SETS avx512skx-i32x16 avx512skx-i32x16)
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.ispc
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/ISPCDuplicateTargetNinja.cmake b/Tests/RunCMake/try_compile/ISPCDuplicateTargetNinja.cmake
index 7f59c14..e08e25f 100644
--- a/Tests/RunCMake/try_compile/ISPCDuplicateTargetNinja.cmake
+++ b/Tests/RunCMake/try_compile/ISPCDuplicateTargetNinja.cmake
@@ -1,11 +1,16 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(ISPC)
-set(CMAKE_ISPC_INSTRUCTION_SETS avx512skx-i32x16
- avx512skx-i32x16)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.ispc
+
+set(CMAKE_ISPC_INSTRUCTION_SETS avx512skx-i32x16 avx512skx-i32x16)
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.ispc
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
+
if(NOT result)
message(FATAL_ERROR "making Ninja and Ninja Multi-Config behave the same")
endif()
diff --git a/Tests/RunCMake/try_compile/ISPCInvalidTarget.cmake b/Tests/RunCMake/try_compile/ISPCInvalidTarget.cmake
index c1ab6f2..2276bd3 100644
--- a/Tests/RunCMake/try_compile/ISPCInvalidTarget.cmake
+++ b/Tests/RunCMake/try_compile/ISPCInvalidTarget.cmake
@@ -1,7 +1,12 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(ISPC)
+
set(CMAKE_ISPC_INSTRUCTION_SETS "avxknl-i32x16")
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.ispc
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.ispc
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/ISPCTargets.cmake b/Tests/RunCMake/try_compile/ISPCTargets.cmake
index 0d3bd43..bd45569 100644
--- a/Tests/RunCMake/try_compile/ISPCTargets.cmake
+++ b/Tests/RunCMake/try_compile/ISPCTargets.cmake
@@ -1,7 +1,12 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(ISPC)
+
set(CMAKE_ISPC_INSTRUCTION_SETS avx512knl-i32x16 avx512skx-i32x16)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.ispc
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.ispc
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/NoArgs-stderr.txt b/Tests/RunCMake/try_compile/NoArgs-stderr.txt
index 8808fd1..72a697e 100644
--- a/Tests/RunCMake/try_compile/NoArgs-stderr.txt
+++ b/Tests/RunCMake/try_compile/NoArgs-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at NoArgs.cmake:1 \(try_compile\):
+CMake Error at NoArgs.cmake:[0-9]+ \(try_compile\):
try_compile unknown error.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NoCStandard-result.txt b/Tests/RunCMake/try_compile/NoCStandard-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_compile/NoCStandard-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_compile/NoCStandard-stderr.txt b/Tests/RunCMake/try_compile/NoCStandard-stderr.txt
new file mode 100644
index 0000000..e0bb9ed
--- /dev/null
+++ b/Tests/RunCMake/try_compile/NoCStandard-stderr.txt
@@ -0,0 +1,7 @@
+CMake Error at NoCStandard.cmake:[0-9]+ \(try_compile\):
+ Error after keyword "C_STANDARD":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NoCStandard.cmake b/Tests/RunCMake/try_compile/NoCStandard.cmake
new file mode 100644
index 0000000..e0d0478
--- /dev/null
+++ b/Tests/RunCMake/try_compile/NoCStandard.cmake
@@ -0,0 +1,4 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ C_STANDARD)
diff --git a/Tests/RunCMake/try_compile/NoCopyFile-stderr.txt b/Tests/RunCMake/try_compile/NoCopyFile-stderr.txt
index d65d9488..55ba687 100644
--- a/Tests/RunCMake/try_compile/NoCopyFile-stderr.txt
+++ b/Tests/RunCMake/try_compile/NoCopyFile-stderr.txt
@@ -1,4 +1,7 @@
-CMake Error at NoCopyFile.cmake:1 \(try_compile\):
- COPY_FILE must be followed by a file path
+CMake Error at NoCopyFile.cmake:[0-9]+ \(try_compile\):
+ Error after keyword "COPY_FILE":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NoCopyFile.cmake b/Tests/RunCMake/try_compile/NoCopyFile.cmake
index 8c648ff..270dff9 100644
--- a/Tests/RunCMake/try_compile/NoCopyFile.cmake
+++ b/Tests/RunCMake/try_compile/NoCopyFile.cmake
@@ -1,2 +1,4 @@
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
COPY_FILE)
diff --git a/Tests/RunCMake/try_compile/NoCopyFile2-stderr.txt b/Tests/RunCMake/try_compile/NoCopyFile2-stderr.txt
index e889524..008d4e9 100644
--- a/Tests/RunCMake/try_compile/NoCopyFile2-stderr.txt
+++ b/Tests/RunCMake/try_compile/NoCopyFile2-stderr.txt
@@ -1,4 +1,7 @@
-CMake Error at NoCopyFile2.cmake:1 \(try_compile\):
- COPY_FILE must be followed by a file path
+CMake Error at NoCopyFile2.cmake:[0-9]+ \(try_compile\):
+ Error after keyword "COPY_FILE":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NoCopyFile2.cmake b/Tests/RunCMake/try_compile/NoCopyFile2.cmake
index 04b7f68..2ea8182 100644
--- a/Tests/RunCMake/try_compile/NoCopyFile2.cmake
+++ b/Tests/RunCMake/try_compile/NoCopyFile2.cmake
@@ -1,2 +1,4 @@
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
COPY_FILE CMAKE_FLAGS -DA=B)
diff --git a/Tests/RunCMake/try_compile/NoCopyFileError-stderr.txt b/Tests/RunCMake/try_compile/NoCopyFileError-stderr.txt
index ed552fd..7ca185d 100644
--- a/Tests/RunCMake/try_compile/NoCopyFileError-stderr.txt
+++ b/Tests/RunCMake/try_compile/NoCopyFileError-stderr.txt
@@ -1,4 +1,7 @@
-CMake Error at NoCopyFileError.cmake:1 \(try_compile\):
- COPY_FILE_ERROR must be followed by a variable name
+CMake Error at NoCopyFileError.cmake:[0-9]+ \(try_compile\):
+ Error after keyword "COPY_FILE_ERROR":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NoCopyFileError.cmake b/Tests/RunCMake/try_compile/NoCopyFileError.cmake
index d4d69ee..1a56e86 100644
--- a/Tests/RunCMake/try_compile/NoCopyFileError.cmake
+++ b/Tests/RunCMake/try_compile/NoCopyFileError.cmake
@@ -1,2 +1,4 @@
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/copied.bin COPY_FILE_ERROR)
diff --git a/Tests/RunCMake/try_compile/NoOutputVariable-stderr.txt b/Tests/RunCMake/try_compile/NoOutputVariable-stderr.txt
index 18ad751..ec29f0b 100644
--- a/Tests/RunCMake/try_compile/NoOutputVariable-stderr.txt
+++ b/Tests/RunCMake/try_compile/NoOutputVariable-stderr.txt
@@ -1,4 +1,7 @@
-CMake Error at NoOutputVariable.cmake:1 \(try_compile\):
- OUTPUT_VARIABLE must be followed by a variable name
+CMake Error at NoOutputVariable.cmake:[0-9]+ \(try_compile\):
+ Error after keyword "OUTPUT_VARIABLE":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NoOutputVariable.cmake b/Tests/RunCMake/try_compile/NoOutputVariable.cmake
index 3b9cb34..13dc4b4 100644
--- a/Tests/RunCMake/try_compile/NoOutputVariable.cmake
+++ b/Tests/RunCMake/try_compile/NoOutputVariable.cmake
@@ -1,2 +1,4 @@
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
OUTPUT_VARIABLE)
diff --git a/Tests/RunCMake/try_compile/NoOutputVariable2-stderr.txt b/Tests/RunCMake/try_compile/NoOutputVariable2-stderr.txt
index 8b2cc25..dd34559 100644
--- a/Tests/RunCMake/try_compile/NoOutputVariable2-stderr.txt
+++ b/Tests/RunCMake/try_compile/NoOutputVariable2-stderr.txt
@@ -1,4 +1,7 @@
-CMake Error at NoOutputVariable2.cmake:1 \(try_compile\):
- OUTPUT_VARIABLE must be followed by a variable name
+CMake Error at NoOutputVariable2.cmake:[0-9]+ \(try_compile\):
+ Error after keyword "OUTPUT_VARIABLE":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NoOutputVariable2.cmake b/Tests/RunCMake/try_compile/NoOutputVariable2.cmake
index ad9ac9a..4d5dda3 100644
--- a/Tests/RunCMake/try_compile/NoOutputVariable2.cmake
+++ b/Tests/RunCMake/try_compile/NoOutputVariable2.cmake
@@ -1,2 +1,4 @@
-try_compile(RESULT ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
OUTPUT_VARIABLE CMAKE_FLAGS -DA=B)
diff --git a/Tests/RunCMake/try_compile/NoSources-stderr.txt b/Tests/RunCMake/try_compile/NoSources-stderr.txt
index 023032b..55603dc 100644
--- a/Tests/RunCMake/try_compile/NoSources-stderr.txt
+++ b/Tests/RunCMake/try_compile/NoSources-stderr.txt
@@ -1,4 +1,7 @@
-CMake Error at NoSources.cmake:1 \(try_compile\):
- SOURCES must be followed by at least one source file
+CMake Error at NoSources.cmake:[0-9]+ \(try_compile\):
+ Error after keyword "SOURCES":
+
+ missing required value
+
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-stderr.txt b/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-stderr.txt
index 025e658..3e48411 100644
--- a/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-stderr.txt
+++ b/Tests/RunCMake/try_compile/NonSourceCompileDefinitions-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at NonSourceCompileDefinitions.cmake:1 \(try_compile\):
+CMake Error at NonSourceCompileDefinitions.cmake:[0-9]+ \(try_compile\):
COMPILE_DEFINITIONS specified on a srcdir type TRY_COMPILE
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/NonSourceCopyFile-stderr.txt b/Tests/RunCMake/try_compile/NonSourceCopyFile-stderr.txt
index f5893e1..7de8c92 100644
--- a/Tests/RunCMake/try_compile/NonSourceCopyFile-stderr.txt
+++ b/Tests/RunCMake/try_compile/NonSourceCopyFile-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at NonSourceCopyFile.cmake:1 \(try_compile\):
+CMake Error at NonSourceCopyFile.cmake:[0-9]+ \(try_compile\):
COPY_FILE specified on a srcdir type TRY_COMPILE
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/ObjCStandard-stderr.txt b/Tests/RunCMake/try_compile/ObjCStandard-stderr.txt
index f1b4df9..59f1d73 100644
--- a/Tests/RunCMake/try_compile/ObjCStandard-stderr.txt
+++ b/Tests/RunCMake/try_compile/ObjCStandard-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at .*/Tests/RunCMake/try_compile/ObjCStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+^CMake Error at .*/Tests/RunCMake/try_compile/ObjCStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists.txt:[0-9]+ \(add_executable\):
OBJC_STANDARD is set to invalid value '3'
+
CMake Error at ObjCStandard.cmake:[0-9]+ \(try_compile\):
diff --git a/Tests/RunCMake/try_compile/ObjCStandard.cmake b/Tests/RunCMake/try_compile/ObjCStandard.cmake
index b2066f9..a691ddd 100644
--- a/Tests/RunCMake/try_compile/ObjCStandard.cmake
+++ b/Tests/RunCMake/try_compile/ObjCStandard.cmake
@@ -1,7 +1,11 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(OBJC)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.m
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.m
OBJC_STANDARD 3
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/ObjCxxStandard-stderr.txt b/Tests/RunCMake/try_compile/ObjCxxStandard-stderr.txt
index a2f91b4..21fa20f 100644
--- a/Tests/RunCMake/try_compile/ObjCxxStandard-stderr.txt
+++ b/Tests/RunCMake/try_compile/ObjCxxStandard-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at .*/Tests/RunCMake/try_compile/ObjCxxStandard-build/CMakeFiles/CMakeTmp/CMakeLists.txt:[0-9]+ \(add_executable\):
+^CMake Error at .*/Tests/RunCMake/try_compile/ObjCxxStandard-build/CMakeFiles/CMake(Tmp|Scratch/TryCompile-[^/]+)/CMakeLists.txt:[0-9]+ \(add_executable\):
OBJCXX_STANDARD is set to invalid value '3'
+
CMake Error at ObjCxxStandard.cmake:[0-9]+ \(try_compile\):
diff --git a/Tests/RunCMake/try_compile/ObjCxxStandard.cmake b/Tests/RunCMake/try_compile/ObjCxxStandard.cmake
index 1221805..b03f560 100644
--- a/Tests/RunCMake/try_compile/ObjCxxStandard.cmake
+++ b/Tests/RunCMake/try_compile/ObjCxxStandard.cmake
@@ -1,7 +1,11 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(OBJCXX)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.mm
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.mm
OBJCXX_STANDARD 3
OUTPUT_VARIABLE out
)
+
message("try_compile output:\n${out}")
diff --git a/Tests/RunCMake/try_compile/OneArg-stderr.txt b/Tests/RunCMake/try_compile/OneArg-stderr.txt
index 12835be..bb0239e 100644
--- a/Tests/RunCMake/try_compile/OneArg-stderr.txt
+++ b/Tests/RunCMake/try_compile/OneArg-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at OneArg.cmake:1 \(try_compile\):
+CMake Error at OneArg.cmake:[0-9]+ \(try_compile\):
try_compile unknown error.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/RunCMakeTest.cmake b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
index eca7bf4..c0fdd9f 100644
--- a/Tests/RunCMake/try_compile/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_compile/RunCMakeTest.cmake
@@ -1,32 +1,28 @@
include(RunCMake)
-run_cmake(CopyFileErrorNoCopyFile)
run_cmake(NoArgs)
run_cmake(OneArg)
run_cmake(TwoArgs)
-run_cmake(NoCopyFile)
-run_cmake(NoCopyFile2)
-run_cmake(NoCopyFileError)
-run_cmake(NoOutputVariable)
-run_cmake(NoOutputVariable2)
run_cmake(NoSources)
-run_cmake(BadLinkLibraries)
-run_cmake(BadSources1)
-run_cmake(BadSources2)
+run_cmake(BinDirEmpty)
+run_cmake(BinDirRelative)
+
+set(RunCMake_TEST_OPTIONS -Dtry_compile_DEFS=old_signature.cmake)
+include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Dtry_compile_DEFS=new_signature.cmake)
+include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake)
+unset(RunCMake_TEST_OPTIONS)
+
run_cmake(NonSourceCopyFile)
run_cmake(NonSourceCompileDefinitions)
-run_cmake(EnvConfig)
-
set(RunCMake_TEST_OPTIONS --debug-trycompile)
run_cmake(PlatformVariables)
run_cmake(WarnDeprecated)
unset(RunCMake_TEST_OPTIONS)
-run_cmake(TargetTypeExe)
-run_cmake(TargetTypeInvalid)
-run_cmake(TargetTypeStatic)
-
if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$" AND
CMAKE_C_COMPILER_ID MATCHES "^(MSVC|GNU|LCC|Clang|AppleClang)$")
set (RunCMake_TEST_OPTIONS -DRunCMake_C_COMPILER_ID=${CMAKE_C_COMPILER_ID})
@@ -34,41 +30,6 @@ if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$" AND
unset (RunCMake_TEST_OPTIONS)
endif()
-if(CMAKE_C_STANDARD_DEFAULT)
- run_cmake(CStandard)
-elseif(DEFINED CMAKE_C_STANDARD_DEFAULT)
- run_cmake(CStandardNoDefault)
-endif()
-if(CMAKE_OBJC_STANDARD_DEFAULT)
- run_cmake(ObjCStandard)
-endif()
-if(CMAKE_CXX_STANDARD_DEFAULT)
- run_cmake(CxxStandard)
-elseif(DEFINED CMAKE_CXX_STANDARD_DEFAULT)
- run_cmake(CxxStandardNoDefault)
-endif()
-if(CMAKE_OBJCXX_STANDARD_DEFAULT)
- run_cmake(ObjCxxStandard)
-endif()
-if(CMake_TEST_CUDA)
- run_cmake(CudaStandard)
-endif()
-if(CMake_TEST_ISPC)
- run_cmake(ISPCTargets)
- run_cmake(ISPCInvalidTarget)
- set(ninja "")
- if(RunCMake_GENERATOR MATCHES "Ninja")
- set(ninja "Ninja")
- endif()
- run_cmake(ISPCDuplicateTarget${ninja})
-endif()
-if((CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) OR CMAKE_C_COMPILER_ID MATCHES "LCC")
- run_cmake(CStandardGNU)
-endif()
-if((CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) OR CMAKE_C_COMPILER_ID MATCHES "LCC")
- run_cmake(CxxStandardGNU)
-endif()
-
run_cmake(CMP0056)
run_cmake(CMP0066)
run_cmake(CMP0067)
diff --git a/Tests/RunCMake/try_compile/TargetTypeExe.cmake b/Tests/RunCMake/try_compile/TargetTypeExe.cmake
index 9b6e727..330f5f5 100644
--- a/Tests/RunCMake/try_compile/TargetTypeExe.cmake
+++ b/Tests/RunCMake/try_compile/TargetTypeExe.cmake
@@ -1,14 +1,20 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(C)
+
set(CMAKE_TRY_COMPILE_TARGET_TYPE EXECUTABLE)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/src.c
OUTPUT_VARIABLE out
COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/copy
COPY_FILE_ERROR copy_err
)
+
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
+
if(copy_err)
message(FATAL_ERROR "try_compile COPY_FILE failed:\n${copy_err}")
endif()
diff --git a/Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt b/Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt
index 08b281a..e9123e3 100644
--- a/Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt
+++ b/Tests/RunCMake/try_compile/TargetTypeInvalid-stderr.txt
@@ -1,4 +1,4 @@
-^CMake Error at TargetTypeInvalid.cmake:2 \(try_compile\):
+^CMake Error at TargetTypeInvalid.cmake:[0-9]+ \(try_compile\):
Invalid value 'INVALID' for CMAKE_TRY_COMPILE_TARGET_TYPE. Only
'EXECUTABLE' and 'STATIC_LIBRARY' are allowed.
Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/try_compile/TargetTypeInvalid.cmake b/Tests/RunCMake/try_compile/TargetTypeInvalid.cmake
index 0bbc4ac..15a20bb 100644
--- a/Tests/RunCMake/try_compile/TargetTypeInvalid.cmake
+++ b/Tests/RunCMake/try_compile/TargetTypeInvalid.cmake
@@ -1,2 +1,6 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
set(CMAKE_TRY_COMPILE_TARGET_TYPE INVALID)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
diff --git a/Tests/RunCMake/try_compile/TargetTypeStatic.cmake b/Tests/RunCMake/try_compile/TargetTypeStatic.cmake
index 006b8b8..98dea41 100644
--- a/Tests/RunCMake/try_compile/TargetTypeStatic.cmake
+++ b/Tests/RunCMake/try_compile/TargetTypeStatic.cmake
@@ -1,14 +1,20 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
enable_language(C)
+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
-try_compile(result ${CMAKE_CURRENT_BINARY_DIR}
- SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/other.c
+
+try_compile(result ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES} ${CMAKE_CURRENT_SOURCE_DIR}/other.c
OUTPUT_VARIABLE out
COPY_FILE ${CMAKE_CURRENT_BINARY_DIR}/copy
COPY_FILE_ERROR copy_err
)
+
if(NOT result)
message(FATAL_ERROR "try_compile failed:\n${out}")
endif()
+
if(copy_err)
message(FATAL_ERROR "try_compile COPY_FILE failed:\n${copy_err}")
endif()
diff --git a/Tests/RunCMake/try_compile/TryRunArgs-stderr.txt b/Tests/RunCMake/try_compile/TryRunArgs-stderr.txt
new file mode 100644
index 0000000..2a58e71
--- /dev/null
+++ b/Tests/RunCMake/try_compile/TryRunArgs-stderr.txt
@@ -0,0 +1,18 @@
+^CMake Warning \(dev\) at TryRunArgs.cmake:[0-9]+ \(try_compile\):
+ Unknown arguments:
+
+ "COMPILE_OUTPUT_VARIABLE"
+ "compOutputVar"
+ "RUN_OUTPUT_VARIABLE"
+ "runOutputVar"
+ "RUN_OUTPUT_STDOUT_VARIABLE"
+ "runOutputStdOutVar"
+ "RUN_OUTPUT_STDERR_VARIABLE"
+ "runOutputStdErrVar"
+ "WORKING_DIRECTORY"
+ "runWorkDir"
+ "ARGS"
+ "runArgs"
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)
+This warning is for project developers. Use -Wno-dev to suppress it.$
diff --git a/Tests/RunCMake/try_compile/TryRunArgs.cmake b/Tests/RunCMake/try_compile/TryRunArgs.cmake
new file mode 100644
index 0000000..e4cb1fe
--- /dev/null
+++ b/Tests/RunCMake/try_compile/TryRunArgs.cmake
@@ -0,0 +1,14 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
+enable_language(C)
+
+try_compile(RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ COPY_FILE "${CMAKE_CURRENT_BINARY_DIR}/out.bin"
+ COMPILE_OUTPUT_VARIABLE compOutputVar
+ RUN_OUTPUT_VARIABLE runOutputVar
+ RUN_OUTPUT_STDOUT_VARIABLE runOutputStdOutVar
+ RUN_OUTPUT_STDERR_VARIABLE runOutputStdErrVar
+ WORKING_DIRECTORY runWorkDir
+ ARGS runArgs
+ )
diff --git a/Tests/RunCMake/try_compile/TwoArgs-stderr.txt b/Tests/RunCMake/try_compile/TwoArgs-stderr.txt
index b9c08fc..38f1d75 100644
--- a/Tests/RunCMake/try_compile/TwoArgs-stderr.txt
+++ b/Tests/RunCMake/try_compile/TwoArgs-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at TwoArgs.cmake:1 \(try_compile\):
+CMake Error at TwoArgs.cmake:[0-9]+ \(try_compile\):
try_compile unknown error.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
diff --git a/Tests/RunCMake/try_compile/new_signature.cmake b/Tests/RunCMake/try_compile/new_signature.cmake
new file mode 100644
index 0000000..cbcb261
--- /dev/null
+++ b/Tests/RunCMake/try_compile/new_signature.cmake
@@ -0,0 +1,2 @@
+set(try_compile_bindir_or_SOURCES SOURCES)
+set(try_compile_redundant_SOURCES "")
diff --git a/Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake b/Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake
new file mode 100644
index 0000000..e156e12
--- /dev/null
+++ b/Tests/RunCMake/try_compile/old_and_new_signature_tests.cmake
@@ -0,0 +1,54 @@
+run_cmake(CopyFileErrorNoCopyFile)
+run_cmake(NoCopyFile)
+run_cmake(NoCopyFile2)
+run_cmake(NoCopyFileError)
+run_cmake(NoCStandard)
+run_cmake(NoOutputVariable)
+run_cmake(NoOutputVariable2)
+run_cmake(BadLinkLibraries)
+run_cmake(BadSources1)
+run_cmake(BadSources2)
+run_cmake(EmptyValueArgs)
+run_cmake(EmptyListArgs)
+run_cmake(TryRunArgs)
+
+run_cmake(EnvConfig)
+
+run_cmake(TargetTypeExe)
+run_cmake(TargetTypeInvalid)
+run_cmake(TargetTypeStatic)
+
+if(CMAKE_C_STANDARD_DEFAULT)
+ run_cmake(CStandard)
+elseif(DEFINED CMAKE_C_STANDARD_DEFAULT)
+ run_cmake(CStandardNoDefault)
+endif()
+if(CMAKE_OBJC_STANDARD_DEFAULT)
+ run_cmake(ObjCStandard)
+endif()
+if(CMAKE_CXX_STANDARD_DEFAULT)
+ run_cmake(CxxStandard)
+elseif(DEFINED CMAKE_CXX_STANDARD_DEFAULT)
+ run_cmake(CxxStandardNoDefault)
+endif()
+if(CMAKE_OBJCXX_STANDARD_DEFAULT)
+ run_cmake(ObjCxxStandard)
+endif()
+if(CMake_TEST_CUDA)
+ run_cmake(CudaStandard)
+endif()
+if(CMake_TEST_ISPC)
+ run_cmake(ISPCTargets)
+ run_cmake(ISPCInvalidTarget)
+ set(ninja "")
+ if(RunCMake_GENERATOR MATCHES "Ninja")
+ set(ninja "Ninja")
+ endif()
+ run_cmake(ISPCDuplicateTarget${ninja})
+endif()
+if((CMAKE_C_COMPILER_ID MATCHES "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.4) OR CMAKE_C_COMPILER_ID MATCHES "LCC")
+ run_cmake(CStandardGNU)
+endif()
+if((CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) OR CMAKE_C_COMPILER_ID MATCHES "LCC")
+ run_cmake(CxxStandardGNU)
+endif()
diff --git a/Tests/RunCMake/try_compile/old_signature.cmake b/Tests/RunCMake/try_compile/old_signature.cmake
new file mode 100644
index 0000000..94b12de
--- /dev/null
+++ b/Tests/RunCMake/try_compile/old_signature.cmake
@@ -0,0 +1,2 @@
+set(try_compile_bindir_or_SOURCES ${CMAKE_CURRENT_BINARY_DIR})
+set(try_compile_redundant_SOURCES SOURCES)
diff --git a/Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt b/Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt
index dcd1bfc..f9cc50e 100644
--- a/Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt
+++ b/Tests/RunCMake/try_run/BadLinkLibraries-stderr.txt
@@ -1,4 +1,4 @@
-CMake Error at BadLinkLibraries.cmake:2 \(try_run\):
+CMake Error at BadLinkLibraries.cmake:[0-9+] \(try_run\):
Only libraries may be used as try_compile or try_run IMPORTED
LINK_LIBRARIES. Got not_a_library of type UTILITY.
Call Stack \(most recent call first\):
diff --git a/Tests/RunCMake/try_run/BadLinkLibraries.cmake b/Tests/RunCMake/try_run/BadLinkLibraries.cmake
index a124bf6..950a942 100644
--- a/Tests/RunCMake/try_run/BadLinkLibraries.cmake
+++ b/Tests/RunCMake/try_run/BadLinkLibraries.cmake
@@ -1,4 +1,7 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
add_custom_target(not_a_library)
-try_run(RUN_RESULT COMPILE_RESULT
- ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+
+try_run(RUN_RESULT COMPILE_RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
LINK_LIBRARIES not_a_library)
diff --git a/Tests/RunCMake/try_run/BinDirEmpty-result.txt b/Tests/RunCMake/try_run/BinDirEmpty-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/BinDirEmpty-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/BinDirEmpty-stderr.txt b/Tests/RunCMake/try_run/BinDirEmpty-stderr.txt
new file mode 100644
index 0000000..def1c22
--- /dev/null
+++ b/Tests/RunCMake/try_run/BinDirEmpty-stderr.txt
@@ -0,0 +1,4 @@
+^CMake Error at BinDirEmpty.cmake:[0-9]+ \(try_run\):
+ No <bindir> specified.
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_run/BinDirEmpty.cmake b/Tests/RunCMake/try_run/BinDirEmpty.cmake
new file mode 100644
index 0000000..d4b7ee3
--- /dev/null
+++ b/Tests/RunCMake/try_run/BinDirEmpty.cmake
@@ -0,0 +1 @@
+try_run(runResultVar compileResultVar "" ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
diff --git a/Tests/RunCMake/try_run/BinDirRelative-result.txt b/Tests/RunCMake/try_run/BinDirRelative-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/BinDirRelative-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/BinDirRelative-stderr.txt b/Tests/RunCMake/try_run/BinDirRelative-stderr.txt
new file mode 100644
index 0000000..54d4e86
--- /dev/null
+++ b/Tests/RunCMake/try_run/BinDirRelative-stderr.txt
@@ -0,0 +1,6 @@
+^CMake Error at BinDirRelative.cmake:[0-9]+ \(try_run\):
+ <bindir> is not an absolute path:
+
+ 'bin_dir_relative'
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_run/BinDirRelative.cmake b/Tests/RunCMake/try_run/BinDirRelative.cmake
new file mode 100644
index 0000000..a277403
--- /dev/null
+++ b/Tests/RunCMake/try_run/BinDirRelative.cmake
@@ -0,0 +1 @@
+try_run(runResultVar compileResultVar bin_dir_relative ${CMAKE_CURRENT_SOURCE_DIR}/src.c)
diff --git a/Tests/RunCMake/try_run/NoCompileOutputVariable-result.txt b/Tests/RunCMake/try_run/NoCompileOutputVariable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoCompileOutputVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/NoCompileOutputVariable-stderr.txt b/Tests/RunCMake/try_run/NoCompileOutputVariable-stderr.txt
new file mode 100644
index 0000000..e8baffb
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoCompileOutputVariable-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at NoCompileOutputVariable.cmake:[0-9]+ \(try_run\):
+ Error after keyword "COMPILE_OUTPUT_VARIABLE":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_run/NoCompileOutputVariable.cmake b/Tests/RunCMake/try_run/NoCompileOutputVariable.cmake
new file mode 100644
index 0000000..9eb7c5e
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoCompileOutputVariable.cmake
@@ -0,0 +1,6 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
+try_run(RUN_RESULT COMPILE_RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ COMPILE_OUTPUT_VARIABLE
+ )
diff --git a/Tests/RunCMake/try_run/NoOutputCompileVariable-result.txt b/Tests/RunCMake/try_run/NoOutputCompileVariable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoOutputCompileVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/NoOutputVariable-result.txt b/Tests/RunCMake/try_run/NoOutputVariable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoOutputVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/NoOutputVariable-stderr.txt b/Tests/RunCMake/try_run/NoOutputVariable-stderr.txt
new file mode 100644
index 0000000..46cfca0
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoOutputVariable-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at NoOutputVariable.cmake:[0-9]+ \(try_run\):
+ Error after keyword "OUTPUT_VARIABLE":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_run/NoOutputVariable.cmake b/Tests/RunCMake/try_run/NoOutputVariable.cmake
new file mode 100644
index 0000000..1901b30
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoOutputVariable.cmake
@@ -0,0 +1,4 @@
+try_run(RUN_RESULT COMPILE_RESULT
+ ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ OUTPUT_VARIABLE
+ )
diff --git a/Tests/RunCMake/try_run/NoRunOutputVariable-result.txt b/Tests/RunCMake/try_run/NoRunOutputVariable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunOutputVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/NoRunOutputVariable-stderr.txt b/Tests/RunCMake/try_run/NoRunOutputVariable-stderr.txt
new file mode 100644
index 0000000..8ccbdab
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunOutputVariable-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at NoRunOutputVariable.cmake:[0-9]+ \(try_run\):
+ Error after keyword "RUN_OUTPUT_VARIABLE":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_run/NoRunOutputVariable.cmake b/Tests/RunCMake/try_run/NoRunOutputVariable.cmake
new file mode 100644
index 0000000..f9e5e0b
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunOutputVariable.cmake
@@ -0,0 +1,6 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
+try_run(RUN_RESULT COMPILE_RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ RUN_OUTPUT_VARIABLE
+ )
diff --git a/Tests/RunCMake/try_run/NoRunStdErrVariable-result.txt b/Tests/RunCMake/try_run/NoRunStdErrVariable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunStdErrVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/NoRunStdErrVariable-stderr.txt b/Tests/RunCMake/try_run/NoRunStdErrVariable-stderr.txt
new file mode 100644
index 0000000..1443ab2
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunStdErrVariable-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at NoRunStdErrVariable.cmake:[0-9]+ \(try_run\):
+ Error after keyword "RUN_OUTPUT_STDERR_VARIABLE":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/try_run/NoRunStdErrVariable.cmake b/Tests/RunCMake/try_run/NoRunStdErrVariable.cmake
new file mode 100644
index 0000000..888bc25
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunStdErrVariable.cmake
@@ -0,0 +1,7 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
+try_run(RUN_RESULT COMPILE_RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp/workdir
+ RUN_OUTPUT_STDERR_VARIABLE
+ )
diff --git a/Tests/RunCMake/try_run/NoRunStdOutVariable-result.txt b/Tests/RunCMake/try_run/NoRunStdOutVariable-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunStdOutVariable-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/NoRunStdOutVariable-stderr.txt b/Tests/RunCMake/try_run/NoRunStdOutVariable-stderr.txt
new file mode 100644
index 0000000..8b90e94
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunStdOutVariable-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at NoRunStdOutVariable.cmake:[0-9]+ \(try_run\):
+ Error after keyword "RUN_OUTPUT_STDOUT_VARIABLE":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:3 \(include\)$
diff --git a/Tests/RunCMake/try_run/NoRunStdOutVariable.cmake b/Tests/RunCMake/try_run/NoRunStdOutVariable.cmake
new file mode 100644
index 0000000..ed6ab88
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoRunStdOutVariable.cmake
@@ -0,0 +1,7 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
+try_run(RUN_RESULT COMPILE_RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp/workdir
+ RUN_OUTPUT_STDOUT_VARIABLE
+ )
diff --git a/Tests/RunCMake/try_run/NoWorkingDirectory-result.txt b/Tests/RunCMake/try_run/NoWorkingDirectory-result.txt
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoWorkingDirectory-result.txt
@@ -0,0 +1 @@
+1
diff --git a/Tests/RunCMake/try_run/NoWorkingDirectory-stderr.txt b/Tests/RunCMake/try_run/NoWorkingDirectory-stderr.txt
new file mode 100644
index 0000000..b6e258f
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoWorkingDirectory-stderr.txt
@@ -0,0 +1,7 @@
+^CMake Error at NoWorkingDirectory.cmake:[0-9]+ \(try_run\):
+ Error after keyword "WORKING_DIRECTORY":
+
+ missing required value
+
+Call Stack \(most recent call first\):
+ CMakeLists.txt:[0-9]+ \(include\)$
diff --git a/Tests/RunCMake/try_run/NoWorkingDirectory.cmake b/Tests/RunCMake/try_run/NoWorkingDirectory.cmake
new file mode 100644
index 0000000..0d68182
--- /dev/null
+++ b/Tests/RunCMake/try_run/NoWorkingDirectory.cmake
@@ -0,0 +1,6 @@
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
+try_run(RUN_RESULT COMPILE_RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ WORKING_DIRECTORY
+ )
diff --git a/Tests/RunCMake/try_run/RunCMakeTest.cmake b/Tests/RunCMake/try_run/RunCMakeTest.cmake
index d74add0..dbea089 100644
--- a/Tests/RunCMake/try_run/RunCMakeTest.cmake
+++ b/Tests/RunCMake/try_run/RunCMakeTest.cmake
@@ -1,6 +1,16 @@
include(RunCMake)
-run_cmake(BadLinkLibraries)
+run_cmake(BinDirEmpty)
+run_cmake(BinDirRelative)
+run_cmake(NoOutputVariable)
+
+set(RunCMake_TEST_OPTIONS -Dtry_compile_DEFS=old_signature.cmake)
+include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake)
+unset(RunCMake_TEST_OPTIONS)
+
+set(RunCMake_TEST_OPTIONS -Dtry_compile_DEFS=new_signature.cmake)
+include(${RunCMake_SOURCE_DIR}/old_and_new_signature_tests.cmake)
+unset(RunCMake_TEST_OPTIONS)
if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$" AND
CMAKE_C_COMPILER_ID MATCHES "^(MSVC|GNU|LCC|Clang|AppleClang)$")
@@ -8,5 +18,3 @@ if (CMAKE_SYSTEM_NAME MATCHES "^(Linux|Darwin|Windows)$" AND
run_cmake(LinkOptions)
unset (RunCMake_TEST_OPTIONS)
endif()
-
-run_cmake(WorkingDirArg)
diff --git a/Tests/RunCMake/try_run/WorkingDirArg.cmake b/Tests/RunCMake/try_run/WorkingDirArg.cmake
index b583823..375a703 100644
--- a/Tests/RunCMake/try_run/WorkingDirArg.cmake
+++ b/Tests/RunCMake/try_run/WorkingDirArg.cmake
@@ -1,6 +1,8 @@
-try_run(RUN_RESULT COMPILE_RESULT
- ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp ${CMAKE_CURRENT_SOURCE_DIR}/src.c
- RUN_OUTPUT_VARIABLE OUTPUT_VARIABLE
+include(${CMAKE_CURRENT_SOURCE_DIR}/${try_compile_DEFS})
+
+try_run(RUN_RESULT COMPILE_RESULT ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/src.c
+ RUN_OUTPUT_VARIABLE RUN_OUTPUT
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/CMakeTmp/workdir
)
diff --git a/Tests/RunCMake/try_run/new_signature.cmake b/Tests/RunCMake/try_run/new_signature.cmake
new file mode 100644
index 0000000..cbcb261
--- /dev/null
+++ b/Tests/RunCMake/try_run/new_signature.cmake
@@ -0,0 +1,2 @@
+set(try_compile_bindir_or_SOURCES SOURCES)
+set(try_compile_redundant_SOURCES "")
diff --git a/Tests/RunCMake/try_run/old_and_new_signature_tests.cmake b/Tests/RunCMake/try_run/old_and_new_signature_tests.cmake
new file mode 100644
index 0000000..2332127
--- /dev/null
+++ b/Tests/RunCMake/try_run/old_and_new_signature_tests.cmake
@@ -0,0 +1,11 @@
+run_cmake(BadLinkLibraries)
+run_cmake(BinDirEmpty)
+run_cmake(BinDirRelative)
+
+run_cmake(WorkingDirArg)
+
+run_cmake(NoCompileOutputVariable)
+run_cmake(NoRunOutputVariable)
+run_cmake(NoRunStdOutVariable)
+run_cmake(NoRunStdErrVariable)
+run_cmake(NoWorkingDirectory)
diff --git a/Tests/RunCMake/try_run/old_signature.cmake b/Tests/RunCMake/try_run/old_signature.cmake
new file mode 100644
index 0000000..94b12de
--- /dev/null
+++ b/Tests/RunCMake/try_run/old_signature.cmake
@@ -0,0 +1,2 @@
+set(try_compile_bindir_or_SOURCES ${CMAKE_CURRENT_BINARY_DIR})
+set(try_compile_redundant_SOURCES SOURCES)
diff --git a/Tests/SwiftOnly/CMakeLists.txt b/Tests/SwiftOnly/CMakeLists.txt
index 01c2222..e92e544 100644
--- a/Tests/SwiftOnly/CMakeLists.txt
+++ b/Tests/SwiftOnly/CMakeLists.txt
@@ -25,6 +25,7 @@ endif()
set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift)
add_executable(SwiftOnly main.swift)
+target_compile_definitions(SwiftOnly PRIVATE SWIFTONLY)
add_library(L L.swift)
diff --git a/Tests/SwiftOnly/main.swift b/Tests/SwiftOnly/main.swift
index 28560d0..a3f1a2c 100644
--- a/Tests/SwiftOnly/main.swift
+++ b/Tests/SwiftOnly/main.swift
@@ -1 +1,7 @@
dump("SwiftOnly")
+
+#if SWIFTONLY
+dump("SWIFTONLY defined")
+#else
+fatalError("SWIFTONLY NOT defined")
+#endif
diff --git a/Tests/TryCompile/CMakeLists.txt b/Tests/TryCompile/CMakeLists.txt
index 000fd2c..a53dd93 100644
--- a/Tests/TryCompile/CMakeLists.txt
+++ b/Tests/TryCompile/CMakeLists.txt
@@ -4,6 +4,18 @@ if(POLICY CMP0129)
endif()
project(TryCompile)
+macro(EXPECT_PASS var out)
+ if(NOT ${var})
+ message(SEND_ERROR "Should pass failed ${out}")
+ endif()
+endmacro()
+
+macro(EXPECT_FAIL var out)
+ if(${var})
+ message(SEND_ERROR "Should fail passed ${out}")
+ endif()
+endmacro()
+
macro(TEST_ASSERT value msg)
if (NOT ${value})
message (SEND_ERROR "Assertion failure:" ${msg} )
@@ -28,138 +40,31 @@ macro(TEST_EXPECT_CONTAINS command expected)
endif()
endmacro()
-
-# try to compile a file that should compile
-# also check that COPY_FILE works
-try_compile(SHOULD_PASS
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/pass.c
- OUTPUT_VARIABLE TRY_OUT
- COPY_FILE ${TryCompile_BINARY_DIR}/CopyOfPass
- )
-
-if(NOT SHOULD_PASS)
- message(SEND_ERROR "should pass failed ${TRY_OUT}")
-endif()
-if(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfPass")
- message(SEND_ERROR "COPY_FILE to \"${TryCompile_BINARY_DIR}/CopyOfPass\" failed")
-else()
- file(REMOVE "${TryCompile_BINARY_DIR}/CopyOfPass")
-endif()
-
-# try to compile a file that should compile
-# also check that COPY_FILE_ERROR works
-file(WRITE ${TryCompile_BINARY_DIR}/invalid "")
-try_compile(SHOULD_PASS
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/pass.c
- OUTPUT_VARIABLE TRY_OUT
- COPY_FILE ${TryCompile_BINARY_DIR}/invalid/path
- COPY_FILE_ERROR _captured
- )
-if(NOT SHOULD_PASS)
- message(SEND_ERROR "should pass failed ${TRY_OUT}")
-endif()
-if(NOT _captured MATCHES "Cannot copy output executable.*/invalid/path")
- message(SEND_ERROR "COPY_FILE_ERROR did not capture expected message")
-endif()
-
-# try to compile a file that should not compile
-try_compile(SHOULD_FAIL
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/fail.c
- OUTPUT_VARIABLE TRY_OUT)
-if(SHOULD_FAIL)
- message(SEND_ERROR "Should fail passed ${TRY_OUT}")
-endif()
-
-# try to compile a file that should compile
-try_compile(SHOULD_PASS
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/pass.c
- OUTPUT_VARIABLE TRY_OUT)
-if(NOT SHOULD_PASS)
- message(SEND_ERROR "should pass failed ${TRY_OUT}")
-endif()
-
-# try to compile a file that should not compile
-try_compile(SHOULD_FAIL
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/fail.c
- OUTPUT_VARIABLE TRY_OUT)
-if(SHOULD_FAIL)
- message(SEND_ERROR "Should fail passed ${TRY_OUT}")
-endif()
-
-# try to compile two files that should compile
-try_compile(SHOULD_PASS
- ${TryCompile_BINARY_DIR}
- SOURCES ${TryCompile_SOURCE_DIR}/pass2a.c ${TryCompile_SOURCE_DIR}/pass2b.cxx
- OUTPUT_VARIABLE TRY_OUT)
-if(NOT SHOULD_PASS)
- message(SEND_ERROR "should pass failed ${TRY_OUT}")
-endif()
-
-# try to compile two files that should not compile
-try_compile(SHOULD_FAIL
- ${TryCompile_BINARY_DIR}
- SOURCES ${TryCompile_SOURCE_DIR}/fail2a.c ${TryCompile_SOURCE_DIR}/fail2b.c
- OUTPUT_VARIABLE TRY_OUT)
-if(SHOULD_FAIL)
- message(SEND_ERROR "Should fail passed ${TRY_OUT}")
-endif()
-
-# try to compile a file that should compile
-set(_c_flags "${CMAKE_C_FLAGS}")
-if(WATCOM)
- string(APPEND CMAKE_C_FLAGS " -dTESTDEF")
-else()
- string(APPEND CMAKE_C_FLAGS " \"-DTESTDEF\"")
-endif()
-try_compile(SHOULD_PASS
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/testdef.c
- OUTPUT_VARIABLE TRY_OUT)
-if(NOT SHOULD_PASS)
- message(SEND_ERROR "should pass failed ${TRY_OUT}")
-endif()
-set(CMAKE_C_FLAGS "${_c_flags}")
-
-if(NOT SHOULD_FAIL)
- if(SHOULD_PASS)
- message("All Tests passed, ignore all previous output.")
- else()
- message("Test failed")
- endif()
-else()
- message("Test failed")
-endif()
-try_compile(CMAKE_ANSI_FOR_SCOPE
- ${TryCompile_BINARY_DIR}
- ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT)
-if (CMAKE_ANSI_FOR_SCOPE)
- message("Compiler supports ansi for")
-else()
- message("Compiler does not support ansi for scope")
-endif()
-
-try_compile(CMAKE_ANSI_FOR_SCOPE
- ${TryCompile_BINARY_DIR}
- ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT)
-if (CMAKE_ANSI_FOR_SCOPE)
- message("Compiler supports ansi for")
-else()
- message("Compiler does not support ansi for scope")
-endif()
-
-message("use the module now")
-include(${CMAKE_ROOT}/Modules/TestForANSIForScope.cmake)
-if (CMAKE_ANSI_FOR_SCOPE)
- message("Compiler supports ansi for")
-else()
- message("Compiler does not support ansi for scope")
-endif()
-
+if (APPLE)
+ enable_language(OBJC)
+ enable_language(OBJCXX)
+endif()
+
+
+# run old signature tests
+set(try_compile_bindir_or_SOURCES ${TryCompile_BINARY_DIR})
+set(try_compile_redundant_SOURCES SOURCES)
+set(try_compile_output_vars OUTPUT_VARIABLE TRY_OUT)
+set(try_compile_compile_output_var TRY_OUT)
+set(try_compile_run_output_var TRY_OUT)
+include(old_and_new_signature_tests.cmake)
+
+# run new signature tests
+set(try_compile_bindir_or_SOURCES SOURCES)
+set(try_compile_redundant_SOURCES "")
+set(try_compile_output_vars
+ COMPILE_OUTPUT_VARIABLE COMPILE_OUT
+ RUN_OUTPUT_VARIABLE RUN_OUTPUT)
+set(try_compile_compile_output_var COMPILE_OUT)
+set(try_compile_run_output_var RUN_OUTPUT)
+include(old_and_new_signature_tests.cmake)
+
+# try to compile a project (old signature)
message("Testing try_compile project mode")
try_compile(TEST_INNER
${TryCompile_BINARY_DIR}/CMakeFiles/Inner
@@ -168,102 +73,8 @@ try_compile(TEST_INNER
OUTPUT_VARIABLE output)
TEST_ASSERT(TEST_INNER "try_compile project mode failed:\n${output}")
-try_compile(COMPILE_DEFINITIONS_LIST_EXPANDED
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/check_a_b.c
- OUTPUT_VARIABLE output
- COMPILE_DEFINITIONS "-DDEF_A;-DDEF_B"
- )
-if(COMPILE_DEFINITIONS_LIST_EXPANDED)
- message(STATUS "COMPILE_DEFINITIONS list expanded correctly")
-else()
- string(REPLACE "\n" "\n " output " ${output}")
- message(SEND_ERROR "COMPILE_DEFINITIONS list did not expand correctly\n${output}")
-endif()
-
-try_compile(SHOULD_FAIL_DUE_TO_BAD_SOURCE
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/pass.c
- OUTPUT_VARIABLE output
- COMPILE_DEFINITIONS "bad#source.c"
- )
-if(SHOULD_FAIL_DUE_TO_BAD_SOURCE AND NOT CMAKE_GENERATOR MATCHES "Watcom WMake|NMake Makefiles")
- string(REPLACE "\n" "\n " output " ${output}")
- message(SEND_ERROR "try_compile with bad#source.c did not fail:\n${output}")
-elseif(NOT output MATCHES [[(bad#source\.c|bad\.c|bad')]])
- string(REPLACE "\n" "\n " output " ${output}")
- message(SEND_ERROR "try_compile with bad#source.c failed without mentioning bad source:\n${output}")
-else()
- message(STATUS "try_compile with bad#source.c correctly failed")
-endif()
-
add_executable(TryCompile pass.c)
-######################################
-
-# now two tests for try_run()
-
-# try to run a file that should compile and run without error
-# also check that OUTPUT_VARIABLE contains both the compile output
-# and the run output
-try_run(SHOULD_RUN SHOULD_COMPILE
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/exit_success.c
- OUTPUT_VARIABLE TRY_OUT)
-if(NOT SHOULD_COMPILE)
- message(SEND_ERROR "exit_success failed compiling: ${TRY_OUT}")
-endif()
-if(NOT "${SHOULD_RUN}" STREQUAL "0")
- message(SEND_ERROR "exit_success failed running with exit code ${SHOULD_RUN}")
-endif()
-# check the compile output for the filename
-if(NOT "${TRY_OUT}" MATCHES "exit_success")
- message(SEND_ERROR " TRY_OUT didn't contain \"exit_success\": \"${TRY_OUT}\"")
-endif()
-# check the run output
-if(NOT "${TRY_OUT}" MATCHES "hello world")
- message(SEND_ERROR " TRY_OUT didn't contain \"hello world\": \"${TRY_OUT}\"")
-endif()
-
-try_run(ARG_TEST_RUN ARG_TEST_COMPILE
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/expect_arg.c
- OUTPUT_VARIABLE TRY_OUT
- ARGS arg1 arg2)
-if(NOT ARG_TEST_COMPILE)
- message(SEND_ERROR "expect_arg failed compiling: ${TRY_OUT}")
-endif()
-if(NOT "${ARG_TEST_RUN}" STREQUAL "0")
- message(SEND_ERROR "expect_arg failed running with exit code ${ARG_TEST_RUN} ${TRY_OUT}")
-endif()
-
-# try to run a file that should compile and run, but return an error
-try_run(SHOULD_EXIT_WITH_ERROR SHOULD_COMPILE
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/exit_with_error.c
- COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
- RUN_OUTPUT_VARIABLE RUN_OUTPUT)
-
-if(NOT SHOULD_COMPILE)
- message(STATUS " exit_with_error failed compiling: ${COMPILE_OUTPUT}")
-endif()
-if("${SHOULD_EXIT_WITH_ERROR}" STREQUAL "0")
- message(SEND_ERROR " exit_with_error passed with exit code ${SHOULD_EXIT_WITH_ERROR}")
-endif()
-
-# check the compile output, it should contain the filename
-if(NOT "${COMPILE_OUTPUT}" MATCHES "exit_with_error")
- message(SEND_ERROR " COMPILE_OUT didn't contain \"exit_with_error\": \"${COMPILE_OUTPUT}\"")
-endif()
-#... but not the run time output
-if("${COMPILE_OUTPUT}" MATCHES "hello world")
- message(SEND_ERROR " COMPILE_OUT contains the run output: \"${COMPILE_OUTPUT}\"")
-endif()
-# check the run output, it should stdout
-if(NOT "${RUN_OUTPUT}" MATCHES "hello world")
- message(SEND_ERROR " RUN_OUTPUT didn't contain \"hello world\": \"${RUN_OUTPUT}\"")
-endif()
-
#######################################################################
#
# also test that the CHECK_C_SOURCE_COMPILES, CHECK_CXX_SOURCE_COMPILES
@@ -382,25 +193,6 @@ if (APPLE)
TEST_ASSERT(SIMPLE_OBJCXX_RUN_SHOULD_WORK "CHECK_OBJCXX_SOURCE_RUNS() failed, but should have succeeded")
TEST_FAIL(OBJCXX_RUN_SHOULD_FAIL "CHECK_OBJCXX_SOURCE_RUNS() succeeds, but should have failed")
TEST_ASSERT(OBJCXX_RUN_SHOULD_WORK "CHECK_OBJCXX_SOURCE_RUNS() failed, but should have succeeded")
-
- # try to compile a file that should compile
- try_compile(SHOULD_PASS
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/pass.m
- OUTPUT_VARIABLE TRY_OUT)
- if(NOT SHOULD_PASS)
- message(SEND_ERROR "should pass failed ${TRY_OUT}")
- endif()
-
- # try to compile a file that should not compile
- try_compile(SHOULD_FAIL
- ${TryCompile_BINARY_DIR}
- ${TryCompile_SOURCE_DIR}/fail.m
- OUTPUT_VARIABLE TRY_OUT)
- if(SHOULD_FAIL)
- message(SEND_ERROR "Should fail passed ${TRY_OUT}")
- endif()
-
endif()
#######################################################################
diff --git a/Tests/TryCompile/old_and_new_signature_tests.cmake b/Tests/TryCompile/old_and_new_signature_tests.cmake
new file mode 100644
index 0000000..c2dd233
--- /dev/null
+++ b/Tests/TryCompile/old_and_new_signature_tests.cmake
@@ -0,0 +1,245 @@
+# try to compile a file that should compile
+try_compile(SHOULD_PASS
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/pass.c
+ OUTPUT_VARIABLE TRY_OUT)
+EXPECT_PASS(SHOULD_PASS "${TRY_OUT}")
+
+# try to compile a file that should compile
+# also check that COPY_FILE works
+try_compile(SHOULD_PASS
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/pass.c
+ OUTPUT_VARIABLE TRY_OUT
+ COPY_FILE ${TryCompile_BINARY_DIR}/CopyOfPass
+ )
+EXPECT_PASS(SHOULD_PASS "${TRY_OUT}")
+
+if(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfPass")
+ message(SEND_ERROR "COPY_FILE to \"${TryCompile_BINARY_DIR}/CopyOfPass\" failed")
+else()
+ file(REMOVE "${TryCompile_BINARY_DIR}/CopyOfPass")
+endif()
+
+# try to compile a file that should compile
+# also check that COPY_FILE_ERROR works
+file(WRITE ${TryCompile_BINARY_DIR}/invalid "")
+try_compile(SHOULD_PASS
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/pass.c
+ OUTPUT_VARIABLE TRY_OUT
+ COPY_FILE ${TryCompile_BINARY_DIR}/invalid/path
+ COPY_FILE_ERROR _captured
+ )
+EXPECT_PASS(SHOULD_PASS "${TRY_OUT}")
+
+if(NOT _captured MATCHES "Cannot copy output executable.*/invalid/path")
+ message(SEND_ERROR "COPY_FILE_ERROR did not capture expected message")
+endif()
+
+# try to compile a file that should not compile
+try_compile(SHOULD_FAIL
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/fail.c
+ OUTPUT_VARIABLE TRY_OUT)
+EXPECT_FAIL(SHOULD_FAIL "${TRY_OUT}")
+
+# try to compile two files that should compile
+try_compile(SHOULD_PASS
+ ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES}
+ ${TryCompile_SOURCE_DIR}/pass2a.c
+ ${TryCompile_SOURCE_DIR}/pass2b.cxx
+ OUTPUT_VARIABLE TRY_OUT)
+EXPECT_PASS(SHOULD_PASS "${TRY_OUT}")
+
+# try to compile two files that should not compile
+try_compile(SHOULD_FAIL
+ ${try_compile_bindir_or_SOURCES}
+ ${try_compile_redundant_SOURCES}
+ ${TryCompile_SOURCE_DIR}/fail2a.c
+ ${TryCompile_SOURCE_DIR}/fail2b.c
+ OUTPUT_VARIABLE TRY_OUT)
+EXPECT_FAIL(SHOULD_FAIL "${TRY_OUT}")
+
+# try to compile a file that should compile
+set(_c_flags "${CMAKE_C_FLAGS}")
+if(WATCOM)
+ string(APPEND CMAKE_C_FLAGS " -dTESTDEF")
+else()
+ string(APPEND CMAKE_C_FLAGS " \"-DTESTDEF\"")
+endif()
+try_compile(SHOULD_PASS
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/testdef.c
+ OUTPUT_VARIABLE TRY_OUT)
+EXPECT_PASS(SHOULD_PASS "${TRY_OUT}")
+set(CMAKE_C_FLAGS "${_c_flags}")
+
+try_compile(CMAKE_ANSI_FOR_SCOPE
+ ${try_compile_bindir_or_SOURCES}
+ ${CMAKE_ROOT}/Modules/TestForAnsiForScope.cxx OUTPUT_VARIABLE OUT)
+if(CMAKE_ANSI_FOR_SCOPE)
+ message("Compiler supports ansi for")
+else()
+ message("Compiler does not support ansi for scope")
+endif()
+
+message("use the module now")
+include(${CMAKE_ROOT}/Modules/TestForANSIForScope.cmake)
+if(CMAKE_ANSI_FOR_SCOPE)
+ message("Compiler supports ansi for")
+else()
+ message("Compiler does not support ansi for scope")
+endif()
+
+# test that COMPILE_DEFINITIONS are correctly expanded
+try_compile(COMPILE_DEFINITIONS_LIST_EXPANDED
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/check_a_b.c
+ OUTPUT_VARIABLE output
+ COMPILE_DEFINITIONS "-DDEF_A;-DDEF_B"
+ )
+if(COMPILE_DEFINITIONS_LIST_EXPANDED)
+ message(STATUS "COMPILE_DEFINITIONS list expanded correctly")
+else()
+ string(REPLACE "\n" "\n " output " ${output}")
+ message(SEND_ERROR "COMPILE_DEFINITIONS list did not expand correctly\n${output}")
+endif()
+
+# try to compile a file that doesn't exist
+try_compile(SHOULD_FAIL_DUE_TO_BAD_SOURCE
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/pass.c
+ OUTPUT_VARIABLE output
+ COMPILE_DEFINITIONS "bad#source.c"
+ )
+if(SHOULD_FAIL_DUE_TO_BAD_SOURCE AND NOT CMAKE_GENERATOR MATCHES "Watcom WMake|NMake Makefiles")
+ string(REPLACE "\n" "\n " output " ${output}")
+ message(SEND_ERROR "try_compile with bad#source.c did not fail:\n${output}")
+elseif(NOT output MATCHES [[(bad#source\.c|bad\.c|bad')]])
+ string(REPLACE "\n" "\n " output " ${output}")
+ message(SEND_ERROR "try_compile with bad#source.c failed without mentioning bad source:\n${output}")
+else()
+ message(STATUS "try_compile with bad#source.c correctly failed")
+endif()
+
+if(APPLE)
+ # try to compile a file that should compile
+ try_compile(SHOULD_PASS
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/pass.m
+ OUTPUT_VARIABLE TRY_OUT)
+ if(NOT SHOULD_PASS)
+ message(SEND_ERROR "should pass failed ${TRY_OUT}")
+ endif()
+
+ # try to compile a file that should not compile
+ try_compile(SHOULD_FAIL
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/fail.m
+ OUTPUT_VARIABLE TRY_OUT)
+ if(SHOULD_FAIL)
+ message(SEND_ERROR "Should fail passed ${TRY_OUT}")
+ endif()
+endif()
+
+######################################
+
+# now test try_run()
+
+# try to run a file that should compile and run without error
+# also check that OUTPUT_VARIABLE contains both the compile output
+# and the run output
+try_run(SHOULD_RUN SHOULD_COMPILE
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/exit_success.c
+ ${try_compile_output_vars})
+if(NOT SHOULD_COMPILE)
+ message(SEND_ERROR
+ "exit_success failed compiling: ${${try_compile_compile_output_var}}")
+endif()
+if(NOT "${SHOULD_RUN}" STREQUAL "0")
+ message(SEND_ERROR
+ "exit_success failed running with exit code ${SHOULD_RUN}")
+endif()
+# check the compile output for the filename
+if(NOT "${${try_compile_compile_output_var}}" MATCHES "exit_success")
+ message(SEND_ERROR
+ " ${try_compile_compile_output_var} didn't contain \"exit_success\":"
+ " \"${${try_compile_compile_output_var}}\"")
+endif()
+# check the run output
+if(NOT "${${try_compile_run_output_var}}" MATCHES "hello world")
+ message(SEND_ERROR
+ " ${try_compile_run_output_var} didn't contain \"hello world\":"
+ " \"${${try_compile_run_output_var}}\"")
+endif()
+
+try_run(ARG_TEST_RUN ARG_TEST_COMPILE
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/expect_arg.c
+ COMPILE_OUTPUT_VARIABLE TRY_OUT
+ ARGS arg1 arg2)
+if(NOT ARG_TEST_COMPILE)
+ message(SEND_ERROR "expect_arg failed compiling: ${TRY_OUT}")
+endif()
+if(NOT "${ARG_TEST_RUN}" STREQUAL "0")
+ message(SEND_ERROR "expect_arg failed running with exit code ${ARG_TEST_RUN} ${TRY_OUT}")
+endif()
+
+# try to run a file that should compile and run, but return an error
+try_run(SHOULD_EXIT_WITH_ERROR SHOULD_COMPILE
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/exit_with_error.c
+ COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
+ RUN_OUTPUT_VARIABLE RUN_OUTPUT)
+
+if(NOT SHOULD_COMPILE)
+ message(STATUS " exit_with_error failed compiling: ${COMPILE_OUTPUT}")
+endif()
+if("${SHOULD_EXIT_WITH_ERROR}" STREQUAL "0")
+ message(SEND_ERROR " exit_with_error passed with exit code ${SHOULD_EXIT_WITH_ERROR}")
+endif()
+
+# check the compile output, it should contain the filename
+if(NOT "${COMPILE_OUTPUT}" MATCHES "exit_with_error")
+ message(SEND_ERROR " COMPILE_OUT didn't contain \"exit_with_error\": \"${COMPILE_OUTPUT}\"")
+endif()
+#... but not the run time output
+if("${COMPILE_OUTPUT}" MATCHES "hello world")
+ message(SEND_ERROR " COMPILE_OUT contains the run output: \"${COMPILE_OUTPUT}\"")
+endif()
+# check the run output, it should contain stdout
+if(NOT "${RUN_OUTPUT}" MATCHES "hello world")
+ message(SEND_ERROR " RUN_OUTPUT didn't contain \"hello world\": \"${RUN_OUTPUT}\"")
+endif()
+
+# try to run a file and parse stdout and stderr separately
+# also check that COPY_FILE works
+try_run(SHOULD_EXIT_WITH_ERROR SHOULD_COMPILE
+ ${try_compile_bindir_or_SOURCES}
+ ${TryCompile_SOURCE_DIR}/stdout_and_stderr.c
+ COPY_FILE ${TryCompile_BINARY_DIR}/CopyOfRun
+ COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
+ RUN_OUTPUT_STDOUT_VARIABLE RUN_OUTPUT_STDOUT
+ RUN_OUTPUT_STDERR_VARIABLE RUN_OUTPUT_STDERR)
+
+if(NOT SHOULD_COMPILE)
+ message(STATUS " exit_with_error failed compiling: ${COMPILE_OUTPUT}")
+endif()
+
+if(NOT EXISTS "${TryCompile_BINARY_DIR}/CopyOfRun")
+ message(SEND_ERROR "COPY_FILE to \"${TryCompile_BINARY_DIR}/CopyOfRun\" failed")
+else()
+ file(REMOVE "${TryCompile_BINARY_DIR}/CopyOfRun")
+endif()
+
+# check the run stdout output
+if(NOT "${RUN_OUTPUT_STDOUT}" MATCHES "hello world")
+ message(SEND_ERROR " RUN_OUTPUT_STDOUT didn't contain \"hello world\": \"${RUN_OUTPUT_STDOUT}\"")
+endif()
+# check the run stderr output
+if(NOT "${RUN_OUTPUT_STDERR}" MATCHES "error")
+ message(SEND_ERROR " RUN_OUTPUT_STDERR didn't contain \"error\": \"${RUN_OUTPUT_STDERR}\"")
+endif()
diff --git a/Tests/TryCompile/stdout_and_stderr.c b/Tests/TryCompile/stdout_and_stderr.c
new file mode 100644
index 0000000..84ded1f
--- /dev/null
+++ b/Tests/TryCompile/stdout_and_stderr.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main()
+{
+ fputs("error\n", stderr);
+ puts("hello world\n");
+ return 0;
+}
diff --git a/Utilities/Doxygen/CMakeLists.txt b/Utilities/Doxygen/CMakeLists.txt
index b712c27..bc16350 100644
--- a/Utilities/Doxygen/CMakeLists.txt
+++ b/Utilities/Doxygen/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeDeveloperReference_STANDALONE 1)
- cmake_minimum_required(VERSION 3.13...3.22 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.13...3.23 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
diff --git a/Utilities/IWYU/mapping.imp b/Utilities/IWYU/mapping.imp
index b80fc22..b0ed911 100644
--- a/Utilities/IWYU/mapping.imp
+++ b/Utilities/IWYU/mapping.imp
@@ -91,7 +91,7 @@
{ symbol: [ "std::__decay_and_strip<cmFindPackageCommand::PathLabel &>::__type", private, "\"cmConfigure.h\"", public ] },
{ symbol: [ "std::__decay_and_strip<cmGlobalNinjaGenerator::TargetAlias &>::__type", private, "\"cmConfigure.h\"", public ] },
{ symbol: [ "std::__decay_and_strip<__gnu_cxx::__normal_iterator<const cmCTestTestHandler::cmCTestTestProperties *, std::vector<cmCTestTestHandler::cmCTestTestProperties, std::allocator<cmCTestTestHandler::cmCTestTestProperties> > > &>::__type", private, "\"cmConfigure.h\"", public ] },
- { symbol: [ "std::__decay_and_strip<const __gnu_cxx::__normal_iterator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> > *, std::vector<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> >, std::allocator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &, void *)> > > > > &>::__type", private, "\"cmConfigure.h\"", public ] },
+ { symbol: [ "std::__decay_and_strip<const __gnu_cxx::__normal_iterator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> > *, std::vector<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> >, std::allocator<std::pair<cm::string_view, std::function<void (ArgumentParser::Instance &)> > > > > &>::__type", private, "\"cmConfigure.h\"", public ] },
{ symbol: [ "std::__success_type<std::chrono::duration<double, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
{ symbol: [ "std::__success_type<std::chrono::duration<long, std::ratio<1, 1000000000> > >::type", private, "\"cmConfigure.h\"", public ] },
{ symbol: [ "std::enable_if<true, std::chrono::duration<long, std::ratio<1, 1> > >::type", private, "\"cmConfigure.h\"", public ] },
diff --git a/Utilities/Release/WiX/CustomAction/CMakeLists.txt b/Utilities/Release/WiX/CustomAction/CMakeLists.txt
index 9d89dd8..dd07f9f 100644
--- a/Utilities/Release/WiX/CustomAction/CMakeLists.txt
+++ b/Utilities/Release/WiX/CustomAction/CMakeLists.txt
@@ -7,6 +7,10 @@ if(MSVC)
"CMAKE_CXX_FLAGS_${CONFIG}"
"${CMAKE_CXX_FLAGS_${CONFIG}}"
)
+ string(REPLACE "-MD" "-MT"
+ "CMAKE_CXX_FLAGS_${CONFIG}"
+ "${CMAKE_CXX_FLAGS_${CONFIG}}"
+ )
endforeach()
endif()
endif()
diff --git a/Utilities/Release/linux/aarch64/Dockerfile b/Utilities/Release/linux/aarch64/Dockerfile
index 9abae2a..e232c01 100644
--- a/Utilities/Release/linux/aarch64/Dockerfile
+++ b/Utilities/Release/linux/aarch64/Dockerfile
@@ -25,7 +25,7 @@ RUN : \
&& nice make -j $(nproc) \
&& if $TEST; then \
# Run tests that require the full build tree.
- bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|CMakeServerLib\.|RunCMake\.ctest_memcheck)'; \
+ bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|RunCMake\.ctest_memcheck)'; \
fi \
&& bin/cpack -G TGZ \
&& bin/cpack -G STGZ \
diff --git a/Utilities/Release/linux/x86_64/Dockerfile b/Utilities/Release/linux/x86_64/Dockerfile
index 8c98d3e..736ee26 100644
--- a/Utilities/Release/linux/x86_64/Dockerfile
+++ b/Utilities/Release/linux/x86_64/Dockerfile
@@ -26,7 +26,7 @@ RUN : \
&& nice make -j $(nproc) \
&& if $TEST; then \
# Run tests that require the full build tree.
- bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|CMakeServerLib\.|RunCMake\.ctest_memcheck)'; \
+ bin/ctest --output-on-failure -j 8 -R '^(CMake\.|CMakeLib\.|RunCMake\.ctest_memcheck)'; \
fi \
&& bin/cpack -G TGZ \
&& bin/cpack -G STGZ \
diff --git a/Utilities/Sphinx/CMakeLists.txt b/Utilities/Sphinx/CMakeLists.txt
index fbce1c8..ffca624 100644
--- a/Utilities/Sphinx/CMakeLists.txt
+++ b/Utilities/Sphinx/CMakeLists.txt
@@ -3,7 +3,7 @@
if(NOT CMake_SOURCE_DIR)
set(CMakeHelp_STANDALONE 1)
- cmake_minimum_required(VERSION 3.13...3.22 FATAL_ERROR)
+ cmake_minimum_required(VERSION 3.13...3.23 FATAL_ERROR)
get_filename_component(tmp "${CMAKE_CURRENT_SOURCE_DIR}" PATH)
get_filename_component(CMake_SOURCE_DIR "${tmp}" PATH)
include(${CMake_SOURCE_DIR}/Modules/CTestUseLaunchers.cmake)
@@ -118,12 +118,12 @@ if(SPHINX_QTHELP)
COMMAND ${CMAKE_COMMAND} "-DCSS_DIR=${CMAKE_CURRENT_BINARY_DIR}/qthelp/_static"
-P "${CMAKE_CURRENT_SOURCE_DIR}/apply_qthelp_css_workaround.cmake"
# Workaround sphinx configurability:
- # https://bitbucket.org/birkenfeld/sphinx/issue/1448/make-qthelp-more-configurable
+ # https://github.com/sphinx-doc/sphinx/issues/1448
COMMAND ${CMAKE_COMMAND} "-DQTHELP_DIR=${CMAKE_CURRENT_BINARY_DIR}/qthelp/"
-P "${CMAKE_CURRENT_SOURCE_DIR}/fixup_qthelp_names.cmake"
# Create proper identifiers. Workaround for
- # https://bitbucket.org/birkenfeld/sphinx/issue/1491/qthelp-should-generate-identifiers-for
+ # https://github.com/sphinx-doc/sphinx/issues/1491
COMMAND "${Python_EXECUTABLE}"
"${CMAKE_CURRENT_SOURCE_DIR}/create_identifiers.py"
"${CMAKE_CURRENT_BINARY_DIR}/qthelp/"
diff --git a/Utilities/cmcurl/CMakeLists.txt b/Utilities/cmcurl/CMakeLists.txt
index f842270..b8cf412 100644
--- a/Utilities/cmcurl/CMakeLists.txt
+++ b/Utilities/cmcurl/CMakeLists.txt
@@ -1465,6 +1465,8 @@ if(MSVC)
add_definitions(-D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE)
if(CMAKE_C_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
+ elseif(CMAKE_C_FLAGS MATCHES "-W[0-4]")
+ string(REGEX REPLACE "-W[0-4]" "-W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
else()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W4")
endif()
diff --git a/Utilities/cmcurl/lib/vtls/openssl.c b/Utilities/cmcurl/lib/vtls/openssl.c
index 635e9c1..5d1203b 100644
--- a/Utilities/cmcurl/lib/vtls/openssl.c
+++ b/Utilities/cmcurl/lib/vtls/openssl.c
@@ -217,8 +217,10 @@
* BoringSSL: supported since 5fd1807d95f7 (committed 2016-09-30)
* LibreSSL: since 2.5.3 (April 12, 2017)
*/
-#if (OPENSSL_VERSION_NUMBER >= 0x10002000L) || \
- defined(OPENSSL_IS_BORINGSSL)
+#if ((OPENSSL_VERSION_NUMBER >= 0x10002000L) && \
+ !(defined(LIBRESSL_VERSION_NUMBER) && \
+ LIBRESSL_VERSION_NUMBER < 0x20503000L)) || \
+ defined(OPENSSL_IS_BORINGSSL)
#define HAVE_SSL_CTX_SET_EC_CURVES
#endif
@@ -2282,6 +2284,14 @@ static void ossl_trace(int direction, int ssl_ver, int content_type,
# define HAS_NPN 1
#endif
+/* Check for OpenSSL 1.1.0 which has set_{min,max}_proto_version(). */
+#undef HAS_MODERN_SET_PROTO_VER
+#if OPENSSL_VERSION_NUMBER >= 0x10100000L \
+ && !(defined(LIBRESSL_VERSION_NUMBER) && \
+ LIBRESSL_VERSION_NUMBER < 0x20600000L)
+# define HAS_MODERN_SET_PROTO_VER 1
+#endif
+
#ifdef HAS_NPN
/*
@@ -2340,7 +2350,7 @@ select_next_proto_cb(SSL *ssl,
}
#endif /* HAS_NPN */
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
+#ifdef HAS_MODERN_SET_PROTO_VER
static CURLcode
set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
{
@@ -2424,7 +2434,7 @@ set_ssl_version_min_max(SSL_CTX *ctx, struct connectdata *conn)
return CURLE_OK;
}
-#endif
+#endif /* HAS_MODERN_SET_PROTO_VER */
#ifdef OPENSSL_IS_BORINGSSL
typedef uint32_t ctx_option_t;
@@ -2434,7 +2444,7 @@ typedef uint64_t ctx_option_t;
typedef long ctx_option_t;
#endif
-#if (OPENSSL_VERSION_NUMBER < 0x10100000L) /* 1.1.0 */
+#if !defined(HAS_MODERN_SET_PROTO_VER)
static CURLcode
set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
struct Curl_easy *data,
@@ -2509,7 +2519,7 @@ set_ssl_version_min_max_legacy(ctx_option_t *ctx_options,
}
return CURLE_OK;
}
-#endif
+#endif /* ! HAS_MODERN_SET_PROTO_VER */
/* The "new session" callback must return zero if the session can be removed
* or non-zero if the session has been put into the session cache.
@@ -2813,7 +2823,7 @@ static CURLcode ossl_connect_step1(struct Curl_easy *data,
ctx_options |= SSL_OP_NO_SSLv2;
ctx_options |= SSL_OP_NO_SSLv3;
-#if (OPENSSL_VERSION_NUMBER >= 0x10100000L) /* 1.1.0 */
+#if HAS_MODERN_SET_PROTO_VER /* 1.1.0 */
result = set_ssl_version_min_max(backend->ctx, conn);
#else
result = set_ssl_version_min_max_legacy(&ctx_options, data, conn,
diff --git a/Utilities/std/cmext/enum_set b/Utilities/std/cmext/enum_set
index 4225b82..d7b8b39 100644
--- a/Utilities/std/cmext/enum_set
+++ b/Utilities/std/cmext/enum_set
@@ -146,6 +146,7 @@ public:
{
this->Set.reset();
this->insert(list);
+ return *this;
}
// Iterators
@@ -298,17 +299,15 @@ public:
{
if (this->contains(e)) {
return iterator(this, static_cast<size_type>(e));
- } else {
- return this->end();
}
+ return this->end();
}
const_iterator find(key_type e) const
{
if (this->contains(e)) {
return const_iterator(this, static_cast<size_type>(e));
- } else {
- return this->end();
}
+ return this->end();
}
bool contains(key_type e) const
@@ -317,6 +316,10 @@ public:
}
private:
+ template <typename E>
+ friend inline bool operator==(const enum_set<E>& lhs,
+ const enum_set<E>& rhs) noexcept;
+
template <typename E, typename Predicate>
friend inline void erase_if(enum_set<E>& set, Predicate pred);
@@ -369,7 +372,7 @@ template <typename Enum>
inline bool operator==(const enum_set<Enum>& lhs,
const enum_set<Enum>& rhs) noexcept
{
- return lhs == rhs;
+ return lhs.Set == rhs.Set;
}
template <typename Enum>
diff --git a/bootstrap b/bootstrap
index 9a87413..d5b071e 100755
--- a/bootstrap
+++ b/bootstrap
@@ -301,6 +301,7 @@ CMAKE_CXX_SOURCES="\
cmBinUtilsWindowsPEDumpbinGetRuntimeDependenciesTool \
cmBinUtilsWindowsPELinker \
cmBinUtilsWindowsPEObjdumpGetRuntimeDependenciesTool \
+ cmBlockCommand \
cmBreakCommand \
cmBuildCommand \
cmCMakeLanguageCommand \
@@ -328,6 +329,7 @@ CMAKE_CXX_SOURCES="\
cmCustomCommand \
cmCustomCommandGenerator \
cmCustomCommandLines \
+ cmCxxModuleMapper \
cmDefinePropertyCommand \
cmDefinitions \
cmDocumentationFormatter \
@@ -337,6 +339,7 @@ CMAKE_CXX_SOURCES="\
cmExecProgramCommand \
cmExecuteProcessCommand \
cmExpandedCommandArgument \
+ cmExperimental \
cmExportBuildFileGenerator \
cmExportFileGenerator \
cmExportInstallFileGenerator \
@@ -391,6 +394,7 @@ CMAKE_CXX_SOURCES="\
cmIncludeRegularExpressionCommand \
cmInstallCommand \
cmInstallCommandArguments \
+ cmInstallCxxModuleBmiGenerator \
cmInstallDirectoryGenerator \
cmInstallExportGenerator \
cmInstallFileSetGenerator \